summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAzka Nathan <darizkyfaz@gmail.com>2024-09-24 09:03:52 +0700
committerAzka Nathan <darizkyfaz@gmail.com>2024-09-24 09:03:52 +0700
commitcc4be72fc2f0d98f8bc2190ea5c404536bb3c56d (patch)
treea00f22741ba1ec63b59659834a9c6177b20db343
parent1f9d0136758531831ea6c7a90556c9a472ed8d40 (diff)
parent649f3037e4357dab42d1a8d799e5f2a2f1fd2e52 (diff)
Merge branch 'production' into unreserved_permission
# Conflicts: # indoteknik_custom/models/sale_order.py
-rw-r--r--indoteknik_api/controllers/api_v1/cart.py2
-rw-r--r--indoteknik_api/controllers/api_v1/partner.py48
-rw-r--r--indoteknik_api/controllers/api_v1/sale_order.py11
-rw-r--r--indoteknik_api/controllers/api_v1/user.py256
-rw-r--r--indoteknik_api/models/res_users.py3
-rw-r--r--indoteknik_custom/models/account_move.py2
-rw-r--r--indoteknik_custom/models/automatic_purchase.py8
-rw-r--r--indoteknik_custom/models/bill_receipt.py10
-rw-r--r--indoteknik_custom/models/dunning_run.py9
-rwxr-xr-xindoteknik_custom/models/product_template.py10
-rwxr-xr-xindoteknik_custom/models/purchase_order.py11
-rw-r--r--indoteknik_custom/models/purchase_order_sales_match.py12
-rw-r--r--indoteknik_custom/models/res_partner.py60
-rwxr-xr-xindoteknik_custom/models/res_users.py18
-rwxr-xr-xindoteknik_custom/models/sale_order.py119
-rw-r--r--indoteknik_custom/models/stock_picking.py3
-rw-r--r--indoteknik_custom/models/user_company_request.py26
-rw-r--r--indoteknik_custom/report/purchase_order.xml16
-rw-r--r--indoteknik_custom/views/account_move.xml1
-rw-r--r--indoteknik_custom/views/bill_receipt.xml2
-rw-r--r--indoteknik_custom/views/dunning_run.xml2
-rwxr-xr-xindoteknik_custom/views/purchase_order.xml8
-rw-r--r--indoteknik_custom/views/res_users.xml197
-rwxr-xr-xindoteknik_custom/views/sale_order.xml3
-rw-r--r--indoteknik_custom/views/user_company_request.xml2
25 files changed, 771 insertions, 68 deletions
diff --git a/indoteknik_api/controllers/api_v1/cart.py b/indoteknik_api/controllers/api_v1/cart.py
index 6bbb812c..2a24b205 100644
--- a/indoteknik_api/controllers/api_v1/cart.py
+++ b/indoteknik_api/controllers/api_v1/cart.py
@@ -16,7 +16,7 @@ class Cart(controller.Controller):
offset = int(kw.get('offset', 0))
query = [('user_id', '=', user_id)]
carts = user_cart.search(query, limit=limit, offset=offset, order='create_date desc')
- carts.write({'source': 'add_to_cart'})
+ # carts.write({'source': 'add_to_cart'})
products = []
products_inactive = []
for cart in carts:
diff --git a/indoteknik_api/controllers/api_v1/partner.py b/indoteknik_api/controllers/api_v1/partner.py
index 69a2f861..663f4d7d 100644
--- a/indoteknik_api/controllers/api_v1/partner.py
+++ b/indoteknik_api/controllers/api_v1/partner.py
@@ -66,6 +66,7 @@ class Partner(controller.Controller):
'name': ['required'],
'email': ['required'],
'mobile': ['required'],
+ 'phone': [''],
'street': ['required'],
'city_id': ['required', 'number', 'alias:kota_id'],
'district_id': ['number', 'alias:kecamatan_id'],
@@ -95,6 +96,7 @@ class Partner(controller.Controller):
'name': ['required'],
'email': ['required'],
'mobile': ['required'],
+ 'phone': [''],
'street': ['required'],
'city_id': ['required', 'number', 'alias:kota_id'],
'district_id': ['number', 'alias:kecamatan_id'],
@@ -121,16 +123,30 @@ class Partner(controller.Controller):
'industry_id': ['number'],
'tax_name': ['alias:nama_wajib_pajak'],
'npwp': [],
+ 'alamat_lengkap_text': [],
+ 'street': [],
+ })
+ id_user = self.get_request_params(kw, {
+ 'id_user': ['number']
+ })
+ params_user = self.get_request_params(kw, {
+ 'company_type_id': ['number'],
+ 'industry_id': ['number'],
+ 'tax_name': ['alias:nama_wajib_pajak'],
+ 'npwp': [],
+ '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)
+ user = request.env[self._name].search([('id', '=', id_user['value']['id_user'])], limit=1)
if not partner:
return self.response(code=404, description='User not found')
-
+
partner.write(params['value'])
+ user.write(params_user['value'])
return self.response({
'id': partner.id
@@ -164,4 +180,32 @@ class Partner(controller.Controller):
})
return self.response(data)
+
+ @http.route(prefix + 'check/<partner_id>/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,
+ 'amount_due': result_tempo,
+ 'remaining_limit': remaining_limit
+ }
+
+ return self.response(data)
+
+
diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py
index e8d18366..e7664c79 100644
--- a/indoteknik_api/controllers/api_v1/sale_order.py
+++ b/indoteknik_api/controllers/api_v1/sale_order.py
@@ -388,6 +388,9 @@ class SaleOrder(controller.Controller):
if not params['valid']:
return self.response(code=400, description=params)
+ # Fetch partner details
+ sales_partner = request.env['res.partner'].browse(params['value']['partner_id'])
+
parameters = {
'warehouse_id': 8,
'carrier_id': 1,
@@ -415,9 +418,11 @@ class SaleOrder(controller.Controller):
'delivery_service_type': params['value']['delivery_service_type'],
'flash_sale': params['value']['flash_sale'],
'note_website': params['value']['note_website'],
- 'customer_type': 'nonpkp',
- 'npwp': '0',
- 'user_id': 3222 # User ID: Nadia Rauhadatul Firdaus
+ 'customer_type': sales_partner.customer_type if sales_partner else 'nonpkp', # Get Customer Type from partner
+ 'npwp': sales_partner.npwp or '0', # Get NPWP from partner
+ 'sppkp': sales_partner.sppkp, # Get SPPKP from partner
+ 'email': sales_partner.email, # Get Email from partner
+ 'user_id': 3222 # User ID: Nadia Rauhadatul Firdaus
}
sales_partner = request.env['res.partner'].browse(parameters['partner_id'])
diff --git a/indoteknik_api/controllers/api_v1/user.py b/indoteknik_api/controllers/api_v1/user.py
index b9fd9f56..7166bd79 100644
--- a/indoteknik_api/controllers/api_v1/user.py
+++ b/indoteknik_api/controllers/api_v1/user.py
@@ -9,6 +9,8 @@ import string
import requests
import json
from difflib import SequenceMatcher
+import mimetypes
+import base64
class User(controller.Controller):
@@ -104,12 +106,28 @@ class User(controller.Controller):
name = kw.get('name')
email = kw.get('email')
password = kw.get('password')
- if not name or not email or not password:
- return self.response(code=400, description='email, name and password is required')
-
- company = kw.get('company', False)
phone = kw.get('phone')
+ # Form Data
+ npwp = kw.get('npwp')
+ npwp_document = kw.get('npwp_document', False)
+ npwp_filename = kw.get('npwp_filename', 'npwp_document')
+ sppkp = kw.get('sppkp', False)
+ sppkp_document = kw.get('sppkp_document', False)
+ sppkp_filename = kw.get('sppkp_filename', 'sppkp_document')
+ email_partner = kw.get('email_partner')
+ business_name = kw.get('business_name', False)
+ industry_id = int(kw.get('industry_id', '0') or 0)
+ company_type_id = int(kw.get('company_type_id', '0') or 0)
+ alamat_wajib_pajak = kw.get('alamat_wajib_pajak', False)
+ alamat_bisnis = kw.get('alamat_bisnis', False)
+ nama_wajib_pajak = kw.get('nama_wajib_pajak', False)
+ is_pkp = kw.get('is_pkp')
+ type_acc = kw.get('type_acc', False)
+
+ if not name or not email or not password:
+ return self.response(code=400, description='email, name, and password are required')
+
response = {
'register': False,
'reason': None
@@ -125,10 +143,11 @@ class User(controller.Controller):
return self.response(response)
+ # Create user data
user_data = {
'name': name,
'login': email,
- 'phone': phone,
+ 'mobile': phone,
'password': password,
'active': False,
'sel_groups_1_9_10': 9
@@ -136,27 +155,91 @@ class User(controller.Controller):
user = request.env['res.users'].create(user_data)
user.partner_id.email = email
+ user.partner_id.mobile = phone
- if company:
+ if type_acc == 'business':
parameter = [
('company_type', '=', 'company'),
- ('name', 'ilike', 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, company).ratio()
+ 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': company
+ 'user_input': business_name
})
else:
- new_company = request.env['res.partner'].create({
- 'name': company
+ 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.partner_id.id,
+ 'user_company_id': new_company.id,
+ 'user_input': business_name
})
- user.parent_id = new_company.id
+
+ 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
+ })
+ 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
+ })
+ new_company.message_post(body="SPPKP Uploaded", attachment_ids=[sppkp_attachment.id])
+
+ if type_acc == 'individu':
+ user.partner_id.customer_type = 'nonpkp'
+ user.partner_id.npwp = '0.000.000.0-000.000'
+ user.partner_id.sppkp = '-'
+ user.partner_id.nama_wajib_pajak = name
+ user.partner_id.user_id = 3222
+ user.partner_id.property_account_receivable_id= 395
+ user.partner_id.property_account_payable_id = 438
user.send_activation_mail()
@@ -239,6 +322,14 @@ class User(controller.Controller):
'activation': True,
'user': self.response_with_token(user)
})
+ parameter = [
+ ('user_id', '=', user.partner_id.id)
+ ]
+ company_request = request.env['user.company.request'].search(parameter, limit=1)
+ if company_request:
+ user.parent_name = company_request.user_input
+ if company_request.is_approve == False:
+ user.send_company_request_mail()
return self.response(response)
@http.route(prefix + 'user/forgot-password', auth='public', methods=['POST'], csrf=False)
@@ -314,3 +405,144 @@ class User(controller.Controller):
x) for x in partners]
return self.response(address)
+
+ @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)
+
+ response = {
+ 'switch': False,
+ 'reason': None
+ }
+
+ # Form Data
+ npwp = kw.get('npwp')
+ npwp_document = kw.get('npwp_document', False)
+ npwp_filename = kw.get('npwp_filename', 'npwp_document')
+ sppkp = kw.get('sppkp', False)
+ sppkp_document = kw.get('sppkp_document', False)
+ sppkp_filename = kw.get('sppkp_filename', 'sppkp_document')
+ email_partner = kw.get('email_partner')
+ business_name = kw.get('business_name', False)
+ industry_id = int(kw.get('industry_id', '0') or 0)
+ company_type_id = int(kw.get('company_type_id', '0') or 0)
+ alamat_wajib_pajak = kw.get('alamat_wajib_pajak', False)
+ alamat_bisnis = kw.get('alamat_bisnis', False)
+ nama_wajib_pajak = kw.get('nama_wajib_pajak', False)
+ is_pkp = kw.get('is_pkp')
+ type_acc = kw.get('type_acc', False)
+
+
+ response = {
+ 'switch': False,
+ 'reason': None
+ }
+
+ if type_acc == 'business':
+ parameter = [
+ ('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 = {
+ '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
+
+ 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
+ })
+ 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
+ })
+ new_company.message_post(body="SPPKP Uploaded", attachment_ids=[sppkp_attachment.id])
+
+ response['switch'] = 'Pending'
+ return self.response(response)
+
+ @http.route(prefix + 'user/<id>/switch_progres', auth='public', methods=['GET', 'OPTIONS'], csrf=False)
+ # @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)
+ response = {
+ 'status': ''
+ }
+ parameter = [
+ ('user_id', '=', id)
+ ]
+ new_company_request = request.env['user.company.request'].search(parameter, limit=1)
+ is_approve = ''
+ if new_company_request:
+ # Mengambil nilai is_approve
+ if new_company_request.is_approve == False:
+ response['status'] = 'pending'
+ else:
+ response['status'] = new_company_request.is_approve
+ else:
+ response['status'] = 'unknown'
+ 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 d5dff876..b2e8acfe 100644
--- a/indoteknik_api/models/res_users.py
+++ b/indoteknik_api/models/res_users.py
@@ -43,6 +43,7 @@ class ResUsers(models.Model):
'type': user.type or '',
'name': user.name or '',
'mobile': user.mobile or '',
+ 'phone': user.phone or '',
'email': user.email or '',
'street': user.street or '',
'street2': user.street2 or '',
@@ -55,6 +56,8 @@ class ResUsers(models.Model):
'tax_name': user.nama_wajib_pajak or '',
'npwp': user.npwp 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,
}
if user.kota_id:
diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py
index a7010bbe..725b3c2d 100644
--- a/indoteknik_custom/models/account_move.py
+++ b/indoteknik_custom/models/account_move.py
@@ -174,7 +174,7 @@ class AccountMove(models.Model):
def _compute_mark_upload_efaktur(self):
for move in self:
- if move.date_efaktur_exported or move.is_efaktur_exported or move.efaktur_document:
+ if move.efaktur_document:
move.mark_upload_efaktur = 'sudah_upload'
else:
move.mark_upload_efaktur = 'belum_upload'
diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py
index 1d1322fa..548115e6 100644
--- a/indoteknik_custom/models/automatic_purchase.py
+++ b/indoteknik_custom/models/automatic_purchase.py
@@ -262,7 +262,7 @@ class AutomaticPurchase(models.Model):
new_po_line = self.env['purchase.order.line'].create([param_line])
line.current_po_id = new_po.id
line.current_po_line_id = new_po_line.id
- self.update_purchase_price_so_line(line)
+ # self.update_purchase_price_so_line(line)
self.create_purchase_order_sales_match(new_po)
@@ -293,6 +293,9 @@ class AutomaticPurchase(models.Model):
sale_ids_set.add(sale_id_with_salesperson)
sale_ids_name.add(sale_order.sale_id.name)
+ margin_item = sale_order.sale_line_id.item_margin / sale_order.qty_so if sale_order.qty_so else 0
+ margin_item = margin_item * sale_order.qty_po
+
matches_so_line = {
'purchase_order_id': purchase_order.id,
'sale_id': sale_order.sale_id.id,
@@ -305,7 +308,8 @@ class AutomaticPurchase(models.Model):
'product_id': sale_order.product_id.id,
'qty_so': sale_order.qty_so,
'qty_po': sale_order.qty_po,
- 'margin_so': sale_order.sale_line_id.item_percent_margin
+ 'margin_so': sale_order.sale_line_id.item_percent_margin,
+ 'margin_item': margin_item
}
po_matches_so_line = self.env['purchase.order.sales.match'].create([matches_so_line])
diff --git a/indoteknik_custom/models/bill_receipt.py b/indoteknik_custom/models/bill_receipt.py
index 76449c1f..7d38d5ad 100644
--- a/indoteknik_custom/models/bill_receipt.py
+++ b/indoteknik_custom/models/bill_receipt.py
@@ -22,8 +22,16 @@ class BillReceipt(models.Model):
resi_tukar_faktur = fields.Char(string='Resi Faktur')
date_terima_tukar_faktur = fields.Date(string='Terima Faktur')
shipper_faktur_id = fields.Many2one('delivery.carrier', string='Shipper Faktur')
- is_validated = fields.Boolean(string='Validated')
+ is_validated = fields.Boolean(string='Validated')
notification = fields.Char(string='Notification')
+ grand_total = fields.Float(string='Grand Total', compute="_compute_grand_total")
+
+ def _compute_grand_total(self):
+ for record in self:
+ grand_total = 0
+ for line in record.bill_line:
+ grand_total += line.total_amt
+ record.grand_total = grand_total
def copy_date_faktur(self):
if not self.is_validated:
diff --git a/indoteknik_custom/models/dunning_run.py b/indoteknik_custom/models/dunning_run.py
index 90159cd0..c167aab7 100644
--- a/indoteknik_custom/models/dunning_run.py
+++ b/indoteknik_custom/models/dunning_run.py
@@ -30,7 +30,14 @@ class DunningRun(models.Model):
is_paid = fields.Boolean(string='Paid')
description = fields.Char(string='Description')
comment = fields.Char(string='Comment')
-
+ grand_total = fields.Float(string='Grand Total', compute="_compute_grand_total")
+
+ def _compute_grand_total(self):
+ for record in self:
+ grand_total = 0
+ for line in record.dunning_line:
+ grand_total += line.total_amt
+ record.grand_total = grand_total
def copy_date_faktur(self):
if not self.is_validated:
diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py
index 000ee3bf..031d1b5b 100755
--- a/indoteknik_custom/models/product_template.py
+++ b/indoteknik_custom/models/product_template.py
@@ -388,8 +388,16 @@ class ProductProduct(models.Model):
if product_template.active and product.active:
if not product.active and len(variants) == 1:
product_template.with_context(skip_active_constraint=True).active = False
+ product_template.unpublished = True
elif not product.active and len(variants) > 1:
- continue
+ all_inactive = all(not variant.active for variant in variants)
+ if all_inactive:
+ product_template.with_context(skip_active_constraint=True).active = False
+ product_template.unpublished = True
+ else:
+ continue
+ if any(variant.active for variant in variants):
+ product_template.unpublished = False
def update_internal_reference_variants(self, limit=100):
variants = self.env['product.product'].search([
diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py
index edcbbb19..8a47482a 100755
--- a/indoteknik_custom/models/purchase_order.py
+++ b/indoteknik_custom/models/purchase_order.py
@@ -69,6 +69,17 @@ class PurchaseOrder(models.Model):
date_done_picking = fields.Datetime(string='Date Done Picking', compute='get_date_done')
bills_dp_id = fields.Many2one('account.move', string='Bills DP')
grand_total = fields.Monetary(string='Grand Total', help='Amount total + amount delivery', compute='_compute_grand_total')
+ total_margin_match = fields.Float(string='Total Margin Match', compute='_compute_total_margin_match')
+
+ def _compute_total_margin_match(self):
+ for purchase in self:
+ match = self.env['purchase.order.sales.match']
+ result = match.read_group(
+ [('purchase_order_id', '=', purchase.id)],
+ ['margin_item'],
+ []
+ )
+ purchase.total_margin_match = result[0].get('margin_item', 0.0)
def _compute_grand_total(self):
for order in self:
diff --git a/indoteknik_custom/models/purchase_order_sales_match.py b/indoteknik_custom/models/purchase_order_sales_match.py
index 78581409..d1d929d3 100644
--- a/indoteknik_custom/models/purchase_order_sales_match.py
+++ b/indoteknik_custom/models/purchase_order_sales_match.py
@@ -20,7 +20,17 @@ class PurchaseOrderSalesMatch(models.Model):
product_id = fields.Many2one('product.product', string='Product')
qty_so = fields.Float(string='Qty SO')
qty_po = fields.Float(string='Qty PO')
- margin_so = fields.Float(string='Margin SO')
+ margin_so = fields.Float(string='Margin SO')
+ margin_item = fields.Float(string='Margin')
+ delivery_amt = fields.Float(string='Delivery Amount', compute='_compute_delivery_amt')
+ margin_deduct = fields.Float(string='After Deduct', compute='_compute_delivery_amt')
+
+ def _compute_delivery_amt(self):
+ for line in self:
+ percent_margin = line.margin_item / line.purchase_order_id.total_margin_match \
+ if line.purchase_order_id.total_margin_match else 0
+ line.delivery_amt = line.purchase_order_id.delivery_amt * percent_margin
+ line.margin_deduct = line.margin_item - line.delivery_amt
@api.onchange('sale_id')
def onchange_sale_id(self):
diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py
index ac126337..ef857c55 100644
--- a/indoteknik_custom/models/res_partner.py
+++ b/indoteknik_custom/models/res_partner.py
@@ -18,7 +18,8 @@ class ResPartner(models.Model):
('pkp', 'PKP'),
('nonpkp', 'Non PKP')
])
- sppkp = fields.Char(string="SPPKP")
+ sppkp = fields.Char(string="SPPKP", tracking=3)
+ npwp = fields.Char(string="NPWP", tracking=3)
counter = fields.Integer(string="Counter", default=0)
leadtime = fields.Integer(string="Leadtime", default=0)
digital_invoice_tax = fields.Boolean(string="Digital Invoice & Faktur Pajak")
@@ -58,20 +59,59 @@ class ResPartner(models.Model):
default=_default_payment_term
)
- def write(self, vals):
- res = super(ResPartner, self).write(vals)
+ @api.depends("street", "street2", "city", "state_id", "country_id", "blok", "nomor", "rt", "rw", "kelurahan_id",
+ "kecamatan_id")
+ def _alamat_lengkap_text(self):
+ for partner in self:
+ if partner.company_type == 'person' and not partner.parent_id:
+ partner.alamat_lengkap_text = partner.street
+ # if partner.company_type == 'person' and partner.parent_id:
+ # partner.alamat_lengkap_text = partner.parent_id.alamat_lengkap_text
- # if 'property_payment_term_id' in vals:
- # if not self.env.user.is_accounting and vals['property_payment_term_id'] != 26:
- # raise UserError('Hanya Finance Accounting yang dapat merubah payment term')
- # group_id = self.env.ref('indoteknik_custom.group_role_merchandiser').id
- # users_in_group = self.env['res.users'].search([('groups_id', 'in', [group_id])])
- # if self.env.user.id not in users_in_group.mapped('id'):
- # raise UserError('You name it')
+ alamat_lengkap_text = fields.Text(string="Alamat Lengkap", required=False , tracking=3)
+ def write(self, vals):
+ res = super(ResPartner, self).write(vals)
+ #
+ # # if 'property_payment_term_id' in vals:
+ # # if not self.env.user.is_accounting and vals['property_payment_term_id'] != 26:
+ # # raise UserError('Hanya Finance Accounting yang dapat merubah payment term')
+ #
+ # # group_id = self.env.ref('indoteknik_custom.group_role_merchandiser').id
+ # # users_in_group = self.env['res.users'].search([('groups_id', 'in', [group_id])])
+ # # if self.env.user.id not in users_in_group.mapped('id'):
+ # # raise UserError('You name it')
+ #
return res
+ # def write(self, vals):
+ # if self.company_type == 'person':
+ # if self.parent_id:
+ # parent = self.parent_id
+ # vals['customer_type'] = parent.customer_type
+ # vals['nama_wajib_pajak'] = parent.nama_wajib_pajak
+ # vals['npwp'] = parent.npwp
+ # vals['sppkp'] = parent.sppkp
+ # vals['alamat_lengkap_text'] = parent.alamat_lengkap_text
+ # vals['industry_id'] = parent.industry_id.id
+ # vals['company_type_id'] = parent.company_type_id.id
+ #
+ # res = super(ResPartner, self).write(vals)
+ # return res
+
+ @api.depends('company_type', 'parent_id', 'npwp', 'sppkp', 'nama_wajib_pajak','alamat_lengkap_text', 'industry_id', 'company_type_id')
+ def _related_fields(self):
+ for partner in self:
+ if partner.company_type == 'person' and partner.parent_id:
+ partner.customer_type = partner.parent_id.customer_type
+ partner.npwp = partner.parent_id.npwp
+ partner.sppkp = partner.parent_id.sppkp
+ partner.nama_wajib_pajak = partner.parent_id.nama_wajib_pajak
+ partner.alamat_lengkap_text = partner.parent_id.alamat_lengkap_text
+ partner.industry_id = partner.parent_id.industry_id.id
+ partner.company_type_id = partner.parent_id.company_type_id.id
+
@api.constrains('property_payment_term_id')
def updated_by_payment_term(self):
for rec in self:
diff --git a/indoteknik_custom/models/res_users.py b/indoteknik_custom/models/res_users.py
index 70a7dc53..5e16aad1 100755
--- a/indoteknik_custom/models/res_users.py
+++ b/indoteknik_custom/models/res_users.py
@@ -13,6 +13,7 @@ class ResUsers(models.Model):
otp_create_date = fields.Datetime(string='OTP Create Date')
payment_terms_id = fields.Many2one('account.payment.term', related='partner_id.property_payment_term_id', string='Payment Terms')
+
def _generate_otp(self):
for user in self:
user.otp_code = '{:04d}'.format(random.randint(0, 9999))
@@ -29,7 +30,22 @@ class ResUsers(models.Model):
user._generate_otp()
user._generate_activation_token()
template.send_mail(user.id, force_send=True)
-
+
+ def send_company_request_mail(self):
+ template = self.env.ref('indoteknik_custom.mail_template_res_user_company_request')
+ 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_request_reject_mail(self):
+ template = self.env.ref('indoteknik_custom.mail_template_res_user_company_request_reject')
+ for user in self:
+ template.send_mail(user.id, force_send=True)
+
def get_activation_token_url(self):
base_url = self.env['ir.config_parameter'].get_param('site.base.url')
return f'{base_url}/register?activation=token&amp;token={self.activation_token}'
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py
index 0690ffa2..d7b24b34 100755
--- a/indoteknik_custom/models/sale_order.py
+++ b/indoteknik_custom/models/sale_order.py
@@ -38,14 +38,14 @@ class SaleOrder(models.Model):
have_outstanding_po = fields.Boolean('Have Outstanding PO', compute='_have_outstanding_po')
purchase_ids = fields.Many2many('purchase.order', string='Purchases', compute='_get_purchases')
real_shipping_id = fields.Many2one(
- 'res.partner', string='Real Delivery Address', readonly=True, required=True,
+ 'res.partner', string='Real Delivery Address', readonly=True,
states={'draft': [('readonly', False)], 'sent': [('readonly', False)], 'sale': [('readonly', False)]},
domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]",
- help="Dipakai untuk alamat tempel")
+ help="Dipakai untuk alamat tempel", tracking=True)
real_invoice_id = fields.Many2one(
'res.partner', string='Delivery Invoice Address', required=True,
domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]",
- help="Dipakai untuk alamat tempel")
+ help="Dipakai untuk alamat tempel", tracking=True)
fee_third_party = fields.Float('Fee Pihak Ketiga')
so_status = fields.Selection([
('terproses', 'Terproses'),
@@ -113,7 +113,60 @@ class SaleOrder(models.Model):
use_button = fields.Boolean(string='Using Calculate Selling Price', copy=False)
unreserve_id = fields.Many2one('stock.picking', 'Unreserve Picking')
voucher_shipping_id = fields.Many2one(comodel_name='voucher', string='Voucher Shipping', copy=False)
-
+ margin_after_delivery_purchase = fields.Float(string='Margin After Delivery Purchase', compute='_compute_margin_after_delivery_purchase')
+ percent_margin_after_delivery_purchase = fields.Float(string='% Margin After Delivery Purchase', compute='_compute_margin_after_delivery_purchase')
+ purchase_delivery_amt = fields.Float(string='Purchase Delivery Amount', compute='_compute_purchase_delivery_amount')
+ type_promotion = fields.Char(string='Type Promotion', compute='_compute_type_promotion')
+ partner_invoice_id = fields.Many2one(
+ 'res.partner', string='Invoice Address',
+ readonly=True, required=True,
+ states={'draft': [('readonly', False)], 'sent': [('readonly', False)], 'sale': [('readonly', False)]},
+ domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]",
+ tracking=True, # Menambahkan tracking=True
+ )
+ partner_shipping_id = fields.Many2one(
+ 'res.partner', string='Delivery Address', readonly=True, required=True,
+ states={'draft': [('readonly', False)], 'sent': [('readonly', False)], 'sale': [('readonly', False)]},
+ domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", tracking=True)
+
+ payment_term_id = fields.Many2one(
+ 'account.payment.term', string='Payment Terms', check_company=True, # Unrequired company
+ domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", tracking=True)
+
+ def _compute_type_promotion(self):
+ for rec in self:
+ promotion_types = []
+ for promotion in rec.order_promotion_ids:
+ for line_program in promotion.program_line_id:
+ if line_program.promotion_type:
+ promotion_types.append(dict(line_program._fields['promotion_type'].selection).get(line_program.promotion_type))
+
+ # Removing duplicates by converting to a set, then back to a list
+ rec.type_promotion = ', '.join(sorted(set(promotion_types)))
+
+ def _compute_purchase_delivery_amount(self):
+ for order in self:
+ match = self.env['purchase.order.sales.match']
+ result2 = match.search([
+ ('sale_id.id', '=', order.id)
+ ])
+ delivery_amt = 0
+ for res in result2:
+ delivery_amt = res.delivery_amt
+ order.purchase_delivery_amt = delivery_amt
+
+ def _compute_margin_after_delivery_purchase(self):
+ for order in self:
+ order.margin_after_delivery_purchase = order.total_margin - order.purchase_delivery_amt
+ if order.amount_untaxed == 0:
+ order.percent_margin_after_delivery_purchase = 0
+ continue
+ if order.shipping_cost_covered == 'indoteknik':
+ delivery_amt = order.delivery_amt
+ else:
+ delivery_amt = 0
+ order.percent_margin_after_delivery_purchase = round((order.margin_after_delivery_purchase / (order.amount_untaxed-delivery_amt-order.fee_third_party)) * 100, 2)
+
def _compute_date_kirim(self):
for rec in self:
picking = self.env['stock.picking'].search([('sale_id', '=', rec.id), ('state', 'not in', ['cancel'])], order='date_doc_kirim desc', limit=1)
@@ -393,10 +446,22 @@ class SaleOrder(models.Model):
# return [('id', 'not in', order_ids)]
# return ['&', ('order_line.invoice_lines.move_id.move_type', 'in', ('out_invoice', 'out_refund')), ('order_line.invoice_lines.move_id', operator, value)]
- @api.onchange('partner_shipping_id')
- def onchange_partner_shipping(self):
- self.real_shipping_id = self.partner_shipping_id
- self.real_invoice_id = self.partner_invoice_id
+
+ def check_data_real_delivery_address(self):
+ real_delivery_address = self.real_shipping_id
+
+ if not real_delivery_address.state_id:
+ raise UserError('State Real Delivery Address harus diisi')
+ if not real_delivery_address.zip:
+ raise UserError('Zip code Real Delivery Address harus diisi')
+ if not real_delivery_address.mobile:
+ raise UserError('Mobile Real Delivery Address harus diisi')
+ if not real_delivery_address.phone:
+ raise UserError('Phone Real Delivery Address harus diisi')
+ if not real_delivery_address.kecamatan_id:
+ raise UserError('Kecamatan Real Delivery Address harus diisi')
+ if not real_delivery_address.kelurahan_id:
+ raise UserError('Kelurahan Real Delivery Address harus diisi')
@api.onchange('partner_id')
def onchange_partner_contact(self):
@@ -638,6 +703,9 @@ class SaleOrder(models.Model):
if not order.commitment_date and order.create_date > datetime(2024, 9, 12):
raise UserError("Expected Delivery Date kosong, wajib diisi")
+ if not order.real_shipping_id:
+ UserError('Real Delivery Address harus di isi')
+
if order.validate_partner_invoice_due():
return self._create_notification_action('Notification', 'Terdapat invoice yang telah melewati batas waktu, mohon perbarui pada dokumen Due Extension')
@@ -999,3 +1067,38 @@ class SaleOrder(models.Model):
order_line.tax_id = tax_id
order_line.discount = discount
order_line.order_id.use_button = True
+
+ @api.model
+ def create(self, vals):
+ # Ensure partner details are updated when a sale order is created
+ order = super(SaleOrder, self).create(vals)
+ order._update_partner_details()
+ return order
+
+ def write(self, vals):
+ # Call the super method to handle the write operation
+ res = super(SaleOrder, self).write(vals)
+
+ # Check if the update is coming from a save operation
+ if any(field in vals for field in ['sppkp', 'npwp', 'email', 'customer_type']):
+ self._update_partner_details()
+
+ return res
+
+ def _update_partner_details(self):
+ for order in self:
+ partner = order.partner_id.parent_id or order.partner_id
+ if partner:
+ # Update partner details
+ partner.sppkp = order.sppkp
+ partner.npwp = order.npwp
+ partner.email = order.email
+ partner.customer_type = order.customer_type
+
+ # Save changes to the partner record
+ partner.write({
+ 'sppkp': partner.sppkp,
+ 'npwp': partner.npwp,
+ 'email': partner.email,
+ 'customer_type': partner.customer_type,
+ }) \ No newline at end of file
diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py
index de45af2e..66a326ff 100644
--- a/indoteknik_custom/models/stock_picking.py
+++ b/indoteknik_custom/models/stock_picking.py
@@ -388,6 +388,9 @@ class StockPicking(models.Model):
if self.picking_type_id.id == 28 and not self.env.user.is_logistic_approver:
raise UserError("Harus di Approve oleh Logistik")
+
+ if self.location_dest_id.id == 47 and not self.env.user.is_purchasing_manager:
+ raise UserError("Transfer ke gudang selisih harus di approve Rafly Hanggara")
if self.group_id.sale_id:
if self.group_id.sale_id.payment_link_midtrans:
diff --git a/indoteknik_custom/models/user_company_request.py b/indoteknik_custom/models/user_company_request.py
index 2467261a..d540b0f6 100644
--- a/indoteknik_custom/models/user_company_request.py
+++ b/indoteknik_custom/models/user_company_request.py
@@ -1,6 +1,6 @@
from odoo import models, fields
from odoo.exceptions import UserError
-
+from odoo.http import request
class UserCompanyRequest(models.Model):
_name = 'user.company.request'
@@ -15,6 +15,8 @@ class UserCompanyRequest(models.Model):
], string='Approval')
def write(self, vals):
+ user = self.get_user_by_email(self.user_id.email)
+ user.parent_name = self.user_input
is_approve = vals.get('is_approve')
if self.is_approve and is_approve:
raise UserError('Tidak dapat mengubah approval yang sudah diisi')
@@ -22,10 +24,28 @@ class UserCompanyRequest(models.Model):
if not self.is_approve and is_approve:
if is_approve == 'approved':
self.user_id.parent_id = self.user_company_id.id
+ self.user_id.customer_type = self.user_company_id.customer_type
+ self.user_id.npwp = self.user_company_id.npwp
+ self.user_id.sppkp = self.user_company_id.sppkp
+ self.user_id.nama_wajib_pajak = self.user_company_id.nama_wajib_pajak
+ self.user_id.alamat_lengkap_text = self.user_company_id.alamat_lengkap_text
+ self.user_id.industry_id = self.user_company_id.industry_id.id
+ self.user_id.company_type_id = self.user_company_id.company_type_id.id
+ self.user_id.user_id = self.user_company_id.user_id
+ self.user_id.property_account_receivable_id = self.user_company_id.property_account_receivable_id
+ self.user_id.property_account_payable_id = self.user_company_id.property_account_payable_id
+ self.user_company_id.active = True
+ user.send_company_request_approve_mail()
else:
new_company = self.env['res.partner'].create({
'name': self.user_input
})
- self.user_id.parent_id = new_company.id
+ # self.user_id.parent_id = new_company.id
+ user.send_company_request_reject_mail()
return super(UserCompanyRequest, self).write(vals)
- \ No newline at end of file
+
+ def get_user_by_email(self, email):
+ return request.env['res.users'].search([
+ ('login', '=', email),
+ ('active', 'in', [True, False])
+ ]) \ No newline at end of file
diff --git a/indoteknik_custom/report/purchase_order.xml b/indoteknik_custom/report/purchase_order.xml
index 98af3188..0f392630 100644
--- a/indoteknik_custom/report/purchase_order.xml
+++ b/indoteknik_custom/report/purchase_order.xml
@@ -11,21 +11,5 @@
<p t-field="o.date_planned" class="m-0"/>
</div>
</xpath>
- <xpath expr="//tr[@class='border-black o_total']" position="after">
- <tr t-if="o.delivery_amt">
- <td name="td_subtotal_label"><strong>Delivery Amt</strong></td>
- <td class="text-right">
- <span t-field="o.delivery_amt"
- t-options='{"widget": "monetary", "display_currency": o.currency_id}'/>
- </td>
- </tr>
- <tr class="border-black" t-if="o.delivery_amt">
- <td name="td_subtotal_label"><strong>Grand Total</strong></td>
- <td class="text-right">
- <span t-field="o.grand_total"
- t-options='{"widget": "monetary", "display_currency": o.currency_id}'/>
- </td>
- </tr>
- </xpath>
</template>
</odoo>
diff --git a/indoteknik_custom/views/account_move.xml b/indoteknik_custom/views/account_move.xml
index 93145fea..2863af57 100644
--- a/indoteknik_custom/views/account_move.xml
+++ b/indoteknik_custom/views/account_move.xml
@@ -85,6 +85,7 @@
</field>
<field name="invoice_date_due" position="after">
<field name="new_due_date" optional="hide"/>
+ <field name="is_efaktur_exported" optional="hide"/>
<field name="invoice_day_to_due" attrs="{'invisible': [['payment_state', 'in', ('paid', 'in_payment', 'reversed')]]}" optional="hide"/>
<field name="new_invoice_day_to_due" attrs="{'invisible': [['payment_state', 'in', ('paid', 'in_payment', 'reversed')]]}" optional="hide"/>
<field name="mark_upload_efaktur" optional="hide" widget="badge"
diff --git a/indoteknik_custom/views/bill_receipt.xml b/indoteknik_custom/views/bill_receipt.xml
index 15d82e7b..02b28ddf 100644
--- a/indoteknik_custom/views/bill_receipt.xml
+++ b/indoteknik_custom/views/bill_receipt.xml
@@ -13,6 +13,7 @@
<field name="resi_tukar_faktur"/>
<field name="date_terima_tukar_faktur"/>
<field name="shipper_faktur_id"/>
+ <field name="grand_total"/>
</tree>
</field>
</record>
@@ -69,6 +70,7 @@
<field name="resi_tukar_faktur"/>
<field name="date_terima_tukar_faktur"/>
<field name="shipper_faktur_id"/>
+ <field name="grand_total"/>
</group>
</group>
<notebook>
diff --git a/indoteknik_custom/views/dunning_run.xml b/indoteknik_custom/views/dunning_run.xml
index dd5bb120..522be8c9 100644
--- a/indoteknik_custom/views/dunning_run.xml
+++ b/indoteknik_custom/views/dunning_run.xml
@@ -13,6 +13,7 @@
<field name="resi_tukar_faktur"/>
<field name="date_terima_tukar_faktur"/>
<field name="shipper_faktur_id"/>
+ <field name="grand_total"/>
</tree>
</field>
</record>
@@ -71,6 +72,7 @@
<field name="resi_tukar_faktur"/>
<field name="date_terima_tukar_faktur"/>
<field name="shipper_faktur_id"/>
+ <field name="grand_total"/>
</group>
</group>
<notebook>
diff --git a/indoteknik_custom/views/purchase_order.xml b/indoteknik_custom/views/purchase_order.xml
index 6bc97bbf..0ef0aa7f 100755
--- a/indoteknik_custom/views/purchase_order.xml
+++ b/indoteknik_custom/views/purchase_order.xml
@@ -27,19 +27,19 @@
<button name="delete_line" type="object" string="Delete " states="draft"/>
</button>
<button name="button_unlock" position="after">
- <button name="create_bill_dp" string="Create Bill DP" type="object" class="oe_highlight" context="{'create_bill':True}" attrs="{'invisible': ['|', ('state', 'not in', ('purchase', 'done')), ('invoice_status', 'in', ('no', 'invoiced'))]}"/>
+ <button name="create_bill_dp" string="Create Bill DP" type="object" class="oe_highlight" attrs="{'invisible': [('state', 'not in', ('purchase', 'done'))]}"/>
</button>
<field name="date_order" position="before">
<field name="sale_order_id" attrs="{'readonly': [('state', 'not in', ['draft'])]}"/>
<field name="sale_order"/>
<field name="is_create_uangmuka"/>
<field name="approval_status"/>
- <field name="amount_total_without_service"/>
</field>
<field name="approval_status" position="after">
<field name="revisi_po" invisible="1"/>
</field>
<field name="incoterm_id" position="after">
+ <field name="amount_total_without_service"/>
<field name="delivery_amt"/>
</field>
<field name="currency_id" position="after">
@@ -48,7 +48,6 @@
<field name="payment_term_id" readonly="1"/>
</field>
<field name="amount_total" position="after">
- <field name="grand_total"/>
<field name="total_margin"/>
<field name="total_so_margin"/>
<field name="total_percent_margin"/>
@@ -237,6 +236,9 @@
<field name="product_id"/>
<field name="qty_so"/>
<field name="qty_po"/>
+ <field name="margin_item" optional="hide"/>
+ <field name="delivery_amt" optional="hide"/>
+ <field name="margin_deduct" optional="hide"/>
<field name="margin_so"/>
</tree>
</field>
diff --git a/indoteknik_custom/views/res_users.xml b/indoteknik_custom/views/res_users.xml
index 976f46c9..39b9d43e 100644
--- a/indoteknik_custom/views/res_users.xml
+++ b/indoteknik_custom/views/res_users.xml
@@ -4,7 +4,8 @@
<field name="name">Users: Activation Request</field>
<field name="model_id" ref="base.model_res_users"/>
<field name="subject">Aktivasi Akun - Indoteknik.com</field>
- <field name="email_from">sales@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="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;">
@@ -59,5 +60,199 @@
</table>
</field>
</record>
+ <record id="mail_template_res_user_company_request" 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">noreply@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.parent_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 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_approve" model="mail.template">
+ <field name="name">Users: Company Request Approve</field>
+ <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="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>Yth. ${object.parent_name},</b></td></tr>
+
+ <tr><td style="padding-bottom: 16px;">Selamat! Pendaftaran akun bisnis Anda di indoteknik.com telah <b>berhasil diverifikasi &amp; sudah aktif.</b> kini anda dapat menikmati berbagai kemudahan dalam berbelanja, antara lain:</td></tr>
+ <tr><td style="padding-bottom: 16px;"><b>Fitur Faktur Pajak &amp; Invoice:</b> Dengan mudah download faktur pajak &amp; Invoice Anda secara digital.</td></tr>
+ <tr><td style="padding-bottom: 16px;"><b>Pembayaran Lengkap:</b> Pilih metode pembayaran yang sesuai dengan kebutuhan Anda, baik transfer bank, VA, kartu kredit, atau pembayaran tempo.</td></tr>
+ <tr><td style="padding-bottom: 16px;"><b>Pelacakan Pengiriman:</b> Lacak status pengiriman pesanan Anda secara real-time.</td></tr>
+ <tr><td style="padding-bottom: 16px;">Untuk memulai transaksi, silakan login Kembali menggunakan akun Anda di <a href="https://indoteknik.com/login">Indoteknik.com</a></td></tr>
+ <tr><td style="padding-bottom: 16px;">Kami sangat senang dapat melayani Anda. Jika ada pertanyaan atau membutuhkan bantuan, jangan ragu untuk menghubungi tim layanan Customer kami di Whatsapp <a href="https://wa.me/6281717181922">0817-1718-1922</a> atau <a href="mailto:sales@indoteknik.com">sales@indoteknik.com</a></td></tr>
+
+ <tr><td style="padding-bottom: 2px;"><b>Hormat kami,</b></td></tr>
+ <tr><td style="padding-bottom: 2px;">Indoteknik.com</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_reject" model="mail.template">
+ <field name="name">Users: Company Request Reject</field>
+ <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="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>Yth. ${object.parent_name},</b></td></tr>
+
+ <tr><td style="padding-bottom: 16px;">Terima kasih atas minat Anda untuk mendaftar akun bisnis di Indoteknik.com. Kami telah menerima permohonan pendaftaran Anda dan saat ini sedang dalam proses review.</td></tr>
+ <tr><td style="padding-bottom: 16px;">Namun, setelah kami lakukan pengecekan, kami menemukan bahwa beberapa informasi yang Anda berikan masih belum lengkap. Untuk dapat melanjutkan proses pendaftaran, mohon kiranya Anda dapat melengkapi data-data berikut:</td></tr>
+ <tr>
+ <td style="padding-bottom: 8px; ">Informasi yang kami butuhkan saat ini adalah:</td>
+ </tr>
+ <tr>
+ <td style="padding: 4px 0; text-align: left;">
+ <ol style="padding-left: 20px; margin: 0;">
+ <li style="padding-bottom: 4px;">Detail Nama Bisnis</li>
+ <li style="padding-bottom: 4px;">Dokumen NPWP</li>
+ <li style="padding-bottom: 4px;">Dokumen SPPKP/Surat Pengukuhan Kena Pajak</li>
+ </ol>
+ </td>
+ </tr>
+
+ <tr><td style="padding-bottom: 16px;">Anda dapat mengirimkan informasi yang kurang tersebut melalui email ini atau dengan menghubungi tim layanan pelanggan kami di <a href="https://wa.me/6281717181922">0817-1718-1922</a> atau <a href="mailto:sales@indoteknik.com">sales@indoteknik.com</a>.</td></tr>
+ <tr><td style="padding-bottom: 16px;">Kami mohon maaf atas ketidaknyamanan ini dan berharap dapat segera menyelesaikan proses pendaftaran akun bisnis Anda.</td></tr>
+ <tr><td style="padding-bottom: 16px;">Terima kasih atas perhatiannya.</td></tr>
+
+ <tr><td style="padding-bottom: 2px;"><b>Hormat kami,</b></td></tr>
+ <tr><td style="padding-bottom: 2px;">Indoteknik.com</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>
</data>
</odoo> \ No newline at end of file
diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml
index 83474df7..3b8a7d1f 100755
--- a/indoteknik_custom/views/sale_order.xml
+++ b/indoteknik_custom/views/sale_order.xml
@@ -32,6 +32,7 @@
<field name="delivery_amt"/>
<field name="fee_third_party"/>
<field name="total_percent_margin"/>
+ <field name="type_promotion"/>
<label for="voucher_id"/>
<div class="o_row">
<field name="voucher_id" id="voucher_id" attrs="{'readonly': ['|', ('state', 'not in', ['draft', 'sent']), ('applied_voucher_id', '!=', False)]}"/>
@@ -69,6 +70,8 @@
<field name="tag_ids" position="after">
<field name="eta_date" readonly="1"/>
<field name="flash_sale"/>
+ <field name="margin_after_delivery_purchase"/>
+ <field name="percent_margin_after_delivery_purchase"/>
</field>
<field name="analytic_account_id" position="after">
<field name="customer_type" required="1"/>
diff --git a/indoteknik_custom/views/user_company_request.xml b/indoteknik_custom/views/user_company_request.xml
index 2efc1e9b..c9edd3f8 100644
--- a/indoteknik_custom/views/user_company_request.xml
+++ b/indoteknik_custom/views/user_company_request.xml
@@ -4,7 +4,7 @@
<field name="name">user.company.request.tree</field>
<field name="model">user.company.request</field>
<field name="arch" type="xml">
- <tree create="0" default_order="is_approve desc">
+ <tree create="0" default_order="create_date desc">
<field name="user_id"/>
<field name="user_company_id"/>
<field name="user_input"/>