summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorit-fixcomart <it@fixcomart.co.id>2024-11-22 09:47:09 +0700
committerit-fixcomart <it@fixcomart.co.id>2024-11-22 09:47:09 +0700
commit14559e52ce09e6e73c220987455c43ce89f9eabf (patch)
treef1376589fe885ef42ea45ab6cb3bc7f71c7d476a
parent755e36e6fed87f787c2a0d31f4318a6eae97e55c (diff)
parent4e84a3c939f50315c5eba4a9ae350f17383b5543 (diff)
Merge branch 'production' into iman/pengajuan-tempo
# Conflicts: # indoteknik_custom/models/res_partner.py
-rw-r--r--indoteknik_api/controllers/api_v1/product.py2
-rw-r--r--indoteknik_api/controllers/api_v1/stock_picking.py10
-rw-r--r--indoteknik_api/models/product_product.py5
-rw-r--r--indoteknik_api/models/sale_order.py2
-rw-r--r--indoteknik_custom/models/approval_unreserve.py2
-rw-r--r--indoteknik_custom/models/automatic_purchase.py66
-rw-r--r--indoteknik_custom/models/res_partner.py25
-rwxr-xr-xindoteknik_custom/models/sale_order.py31
-rw-r--r--indoteknik_custom/models/sale_order_line.py7
-rw-r--r--indoteknik_custom/models/solr/product_product.py2
-rw-r--r--indoteknik_custom/models/stock_picking.py81
-rw-r--r--indoteknik_custom/models/vendor_approval.py2
-rw-r--r--indoteknik_custom/models/wati.py57
-rw-r--r--indoteknik_custom/models/website_user_cart.py2
-rw-r--r--indoteknik_custom/views/partner_payment_term.xml3
-rw-r--r--indoteknik_custom/views/res_partner.xml11
-rwxr-xr-xindoteknik_custom/views/sale_order.xml41
-rw-r--r--indoteknik_custom/views/stock_picking.xml1
18 files changed, 236 insertions, 114 deletions
diff --git a/indoteknik_api/controllers/api_v1/product.py b/indoteknik_api/controllers/api_v1/product.py
index b68eb0f9..32362582 100644
--- a/indoteknik_api/controllers/api_v1/product.py
+++ b/indoteknik_api/controllers/api_v1/product.py
@@ -103,7 +103,7 @@ class Product(controller.Controller):
product = request.env['product.product'].search(
[('id', '=', id)], limit=1)
- qty_available = product.free_qty
+ qty_available = product.qty_free_bandengan
data = {
'qty': qty_available,
diff --git a/indoteknik_api/controllers/api_v1/stock_picking.py b/indoteknik_api/controllers/api_v1/stock_picking.py
index ea8c6400..110cde8a 100644
--- a/indoteknik_api/controllers/api_v1/stock_picking.py
+++ b/indoteknik_api/controllers/api_v1/stock_picking.py
@@ -32,7 +32,9 @@ class StockPicking(controller.Controller):
pending_domain = [('driver_departure_date', '=', False), ('driver_arrival_date', '=', False)]
shipment_domain = [('driver_departure_date', '!=', False), ('driver_arrival_date', '=', False)]
- completed_domain = [('driver_departure_date', '!=', False), ('driver_arrival_date', '!=', False)]
+ shipment_domain2 = [('driver_departure_date', '!=', False), ('sj_return_date', '=', False)]
+ completed_domain = [('driver_departure_date', '!=', False),'|', ('driver_arrival_date', '!=', False), ('sj_return_date', '!=', False)]
+ completed_domain2 = [('driver_departure_date', '!=', False), ('sj_return_date', '!=', False)]
picking_model = request.env['stock.picking']
domain = [
@@ -74,7 +76,7 @@ class StockPicking(controller.Controller):
'name': picking.sale_id.name,
'client_order_ref': picking.sale_id.client_order_ref or ''
},
- 'delivered': picking.waybill_id.delivered or picking.driver_arrival_date != False,
+ 'delivered': picking.waybill_id.delivered or picking.driver_arrival_date != False or picking.sj_return_date != False,
'status': picking.shipping_status,
'carrier_name': picking.carrier_id.name or '',
'last_manifest': next(iter(manifests), None)
@@ -83,8 +85,8 @@ class StockPicking(controller.Controller):
return self.response({
'summary': {
'pending_count': picking_model.search_count(default_domain + pending_domain),
- 'shipment_count': picking_model.search_count(default_domain + shipment_domain),
- 'completed_count': picking_model.search_count(default_domain + completed_domain)
+ 'shipment_count': picking_model.search_count(default_domain + shipment_domain + shipment_domain2),
+ 'completed_count': picking_model.search_count(default_domain + completed_domain )
},
'picking_total': picking_model.search_count(domain),
'pickings': res_pickings
diff --git a/indoteknik_api/models/product_product.py b/indoteknik_api/models/product_product.py
index 386ddb6a..f8869c7d 100644
--- a/indoteknik_api/models/product_product.py
+++ b/indoteknik_api/models/product_product.py
@@ -61,8 +61,9 @@ class ProductProduct(models.Model):
price_for = self.env.context.get('price_for', 'odoo')
pricelist = pricelist or self.env.context.get('user_pricelist')
default_price_tier = '1_v2'
-
- price_tier = pricelist.get_tier_level()
+ price_tier = []
+ if pricelist:
+ price_tier = pricelist.get_tier_level()
price_tier = price_tier if price_tier else default_price_tier
pricelist = self._get_pricelist_tier(price_tier)
diff --git a/indoteknik_api/models/sale_order.py b/indoteknik_api/models/sale_order.py
index 8e0371a3..54e1fd40 100644
--- a/indoteknik_api/models/sale_order.py
+++ b/indoteknik_api/models/sale_order.py
@@ -33,7 +33,7 @@ class SaleOrder(models.Model):
'id': picking.id,
'name': picking.name,
'tracking_number': picking.delivery_tracking_no or '',
- 'delivered': picking.waybill_id.delivered or picking.driver_arrival_date != False,
+ 'delivered': picking.waybill_id.delivered or picking.driver_arrival_date != False or picking.sj_return_date != False,
})
if sale_order.state == 'cancel':
data['status'] = 'cancel'
diff --git a/indoteknik_custom/models/approval_unreserve.py b/indoteknik_custom/models/approval_unreserve.py
index ba8b8da7..d847ea37 100644
--- a/indoteknik_custom/models/approval_unreserve.py
+++ b/indoteknik_custom/models/approval_unreserve.py
@@ -86,7 +86,7 @@ class ApprovalUnreserve(models.Model):
})
# Trigger the unreserve function
self._trigger_unreserve()
- self.picking_id.check_state_reserve()
+ # self.picking_id.check_state_reserve()
def action_reject(self, reason):
if self.env.user.id != self.user_id.id:
diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py
index 548115e6..4e96e6d4 100644
--- a/indoteknik_custom/models/automatic_purchase.py
+++ b/indoteknik_custom/models/automatic_purchase.py
@@ -401,36 +401,40 @@ class AutomaticPurchase(models.Model):
domain = [
('product_id', '=', line.product_id.id)
]
- sale = self.env['v.sales.outstanding'].search(domain, order='sale_order_create_date desc', limit=1)
-
- existing_match = self.env['automatic.purchase.sales.match'].search([
- ('automatic_purchase_id', '=', self.id),
- ('sale_id', '=', sale.sale_id.id),
- ('product_id', '=', sale.product_id.id),
- ])
+ sales = self.env['v.sales.outstanding'].search(domain, order='sale_order_create_date desc')
- price_so = self.env['sale.order.line'].search([
- ('id', '=', sale.sale_line_id.id),
- ])
-
- if existing_match:
- continue
+ for sale in sales:
+ existing_match = self.env['automatic.purchase.sales.match'].search([
+ ('automatic_purchase_id', '=', self.id),
+ ('sale_id', '=', sale.sale_id.id),
+ ('sale_line_id', '=', sale.sale_line_id.id),
+ ('product_id', '=', sale.product_id.id),
+ ])
- self.env['automatic.purchase.sales.match'].create([{
- 'automatic_purchase_id': self.id,
- 'sale_id': sale.sale_id.id,
- 'sale_line_id': sale.sale_line_id.id,
- 'picking_id': sale.picking_id.id,
- 'move_id': sale.move_id.id,
- 'partner_id': sale.partner_id.id,
- 'partner_invoice_id': sale.partner_invoice_id.id,
- 'salesperson_id': sale.salesperson_id.id,
- 'product_id': sale.product_id.id,
- 'qty_so': sale.outgoing,
- 'qty_po': line.qty_purchase,
- 'purchase_price': price_so.purchase_price,
- 'purchase_tax_id': price_so.purchase_tax_id.id if price_so.purchase_tax_id.id else None,
- }])
+ # price_so = self.env['sale.order.line'].search([
+ # ('id', '=', sale.sale_line_id.id),
+ # ])
+
+ if existing_match:
+ continue
+
+ self.env['automatic.purchase.sales.match'].create([{
+ 'automatic_purchase_id': self.id,
+ 'sale_id': sale.sale_id.id,
+ 'sale_line_id': sale.sale_line_id.id,
+ 'picking_id': sale.picking_id.id,
+ 'move_id': sale.move_id.id,
+ 'partner_id': sale.partner_id.id,
+ 'partner_invoice_id': sale.partner_invoice_id.id,
+ 'salesperson_id': sale.salesperson_id.id,
+ 'product_id': sale.product_id.id,
+ 'qty_so': sale.outgoing,
+ 'qty_po': line.qty_purchase,
+ 'purchase_price': sale.sale_line_id.purchase_price,
+ 'purchase_tax_id': sale.sale_line_id.purchase_tax_id.id if sale.sale_line_id.purchase_tax_id.id else None,
+ # 'purchase_price': price_so.purchase_price,
+ # 'purchase_tax_id': price_so.purchase_tax_id.id if price_so.purchase_tax_id.id else None,
+ }])
def _create_sync_purchasing_job(self, jobs):
date = datetime.utcnow()
@@ -462,9 +466,9 @@ class AutomaticPurchase(models.Model):
count = 0
for point in orderpoints:
# _logger.info('test %s' % point.product_id.name)
- if point.product_id.virtual_available > point.product_min_qty:
+ if point.product_id.qty_available_bandengan > point.product_min_qty:
continue
- qty_purchase = point.product_max_qty - point.product_id.virtual_available
+ qty_purchase = point.product_max_qty - point.product_id.qty_available_bandengan
po_line = self.env['purchase.order.line'].search([('product_id', '=', point.product_id.id), ('order_id.state', '=', 'done')], order='id desc', limit=1)
if self.vendor_id:
@@ -491,7 +495,7 @@ class AutomaticPurchase(models.Model):
'qty_purchase': qty_purchase,
'qty_min': point.product_min_qty,
'qty_max': point.product_max_qty,
- 'qty_available': point.product_id.virtual_available,
+ 'qty_available': point.product_id.qty_available_bandengan,
# 'partner_id': po_line.order_id.partner_id.id,
# 'last_price': po_line.price_unit,
'partner_id': vendor_id,
diff --git a/indoteknik_custom/models/res_partner.py b/indoteknik_custom/models/res_partner.py
index ec027ec1..9d1b70f8 100644
--- a/indoteknik_custom/models/res_partner.py
+++ b/indoteknik_custom/models/res_partner.py
@@ -11,6 +11,16 @@ class GroupPartner(models.Model):
class ResPartner(models.Model):
_inherit = 'res.partner'
+ property_account_payable_id = fields.Many2one('account.account', company_dependent=True,
+ string="Account Payable",
+ domain="[('internal_type', '=', 'payable'), ('deprecated', '=', False), ('company_id', '=', current_company_id)]",
+ help="This account will be used instead of the default one as the payable account for the current partner",
+ default=438)
+ property_account_receivable_id = fields.Many2one('account.account', company_dependent=True,
+ string="Account Receivable",
+ domain="[('internal_type', '=', 'receivable'), ('deprecated', '=', False), ('company_id', '=', current_company_id)]",
+ help="This account will be used instead of the default one as the receivable account for the current partner",
+ default=395)
# Referensi
supplier_ids = fields.Many2many('user.pengajuan.tempo.line', string="Suppliers")
@@ -85,7 +95,7 @@ class ResPartner(models.Model):
counter = fields.Integer(string="Counter", default=0)
leadtime = fields.Integer(string="Leadtime", default=0)
digital_invoice_tax = fields.Boolean(string="Digital Invoice & Faktur Pajak")
- is_potential = fields.Boolean(string='Potential')
+ is_not_potential = fields.Boolean(string='Not Potential')
pakta_integritas = fields.Boolean(string='Pakta Integritas')
use_so_approval = fields.Boolean(string='Use SO Approval')
@@ -116,6 +126,16 @@ class ResPartner(models.Model):
company_type = fields.Selection(string='Company Type',
selection=[('person', 'Individual'), ('company', 'Company')],
compute='_compute_company_type', inverse='_write_company_type', tracking=3)
+ warning_stage = fields.Float(string='Warning Amount',
+ help="A warning message will appear once the "
+ "selected customer is crossed warning "
+ "amount. Set its value to 0.00 to"
+ " disable this feature", tracking=3)
+ blocking_stage = fields.Float(string='Blocking Amount',
+ help="Cannot make sales once the selected "
+ "customer is crossed blocking amount."
+ "Set its value to 0.00 to disable "
+ "this feature", tracking=3)
@api.model
def _default_payment_term(self):
@@ -307,8 +327,7 @@ class ResPartner(models.Model):
# 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')
+ @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:
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py
index 75332996..5e868edd 100755
--- a/indoteknik_custom/models/sale_order.py
+++ b/indoteknik_custom/models/sale_order.py
@@ -626,20 +626,6 @@ class SaleOrder(models.Model):
# return ['&', ('order_line.invoice_lines.move_id.move_type', 'in', ('out_invoice', 'out_refund')), ('order_line.invoice_lines.move_id', operator, value)]
- # 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')
-
@api.onchange('partner_id')
def onchange_partner_contact(self):
parent_id = self.partner_id.parent_id
@@ -650,6 +636,7 @@ class SaleOrder(models.Model):
self.customer_type = parent_id.customer_type
self.email = parent_id.email
self.pareto_status = parent_id.pareto_status
+ self.user_id = parent_id.user_id
@api.onchange('partner_id')
def onchange_partner_id(self):
@@ -762,7 +749,7 @@ class SaleOrder(models.Model):
raise UserError("Salesperson sudah tidak aktif, mohon diisi yang benar pada data SO dan Contact")
def sale_order_approve(self):
- if self.validate_different_vendor() and not self.vendor_approval and not self.vendor_approval_id:
+ if self.validate_different_vendor() and not self.vendor_approval:
return self._create_notification_action('Notification', 'Terdapat Vendor yang berbeda dengan MD Vendor')
self.check_due()
@@ -939,7 +926,7 @@ class SaleOrder(models.Model):
def action_confirm(self):
for order in self:
- if self.validate_different_vendor() and not self.vendor_approval and not self.vendor_approval_id:
+ if self.validate_different_vendor() and not self.vendor_approval:
return self._create_notification_action('Notification', 'Terdapat Vendor yang berbeda dengan MD Vendor')
order.check_data_real_delivery_address()
@@ -980,6 +967,16 @@ class SaleOrder(models.Model):
# order.order_line.get_reserved_from()
res = super(SaleOrder, self).action_confirm()
+ for order in self:
+ note = []
+ for line in order.order_line:
+ if line.display_type == 'line_note':
+ note.append(line.name)
+
+ if order.picking_ids:
+ # Sort picking_ids by creation date to get the most recent one
+ latest_picking = order.picking_ids.sorted(key=lambda p: p.create_date, reverse=True)[0]
+ latest_picking.notee = '\n'.join(note)
return res
def action_cancel(self):
@@ -1063,6 +1060,8 @@ class SaleOrder(models.Model):
partner.email = self.email
if not partner.customer_type:
partner.customer_type = self.customer_type
+ if not partner.user_id:
+ partner.user_id = self.user_id.id
# if not partner.sppkp or not partner.npwp or not partner.email or partner.customer_type:
# partner.customer_type = self.customer_type
diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py
index 5a6640ec..04fafa69 100644
--- a/indoteknik_custom/models/sale_order_line.py
+++ b/indoteknik_custom/models/sale_order_line.py
@@ -37,6 +37,11 @@ class SaleOrderLine(models.Model):
weight = fields.Float(string='Weight')
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')
+
+ def _get_qty_free_bandengan(self):
+ for line in self:
+ line.qty_free_bu = line.product_id.qty_free_bandengan
@api.constrains('note_procurement')
def note_procurement_to_apo(self):
@@ -372,5 +377,5 @@ class SaleOrderLine(models.Model):
continue
if not line.product_id.product_tmpl_id.sale_ok:
raise UserError('Product %s belum bisa dijual, harap hubungi finance' % line.product_id.display_name)
- if not line.vendor_id or not line.purchase_price:
+ if not line.vendor_id or not line.purchase_price and not line.display_type == 'line_note':
raise UserError(_('Isi Vendor dan Harga Beli sebelum Request Approval')) \ No newline at end of file
diff --git a/indoteknik_custom/models/solr/product_product.py b/indoteknik_custom/models/solr/product_product.py
index dd1d40f6..667511b2 100644
--- a/indoteknik_custom/models/solr/product_product.py
+++ b/indoteknik_custom/models/solr/product_product.py
@@ -54,7 +54,7 @@ class ProductProduct(models.Model):
('location_id', 'in', target_locations),
])
- is_in_bu = any(quant.available_quantity > 0 for quant in stock_quant)
+ is_in_bu = True if variant.qty_free_bandengan > 0 else False
document = solr_model.get_doc('variants', variant.id)
diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py
index 50e9304b..10b26711 100644
--- a/indoteknik_custom/models/stock_picking.py
+++ b/indoteknik_custom/models/stock_picking.py
@@ -34,7 +34,6 @@ class StockPicking(models.Model):
)
driver_arrival_date = fields.Datetime(
string='Delivery Arrival Date',
- readonly=True,
copy=False
)
delivery_tracking_no = fields.Char(
@@ -112,6 +111,7 @@ class StockPicking(models.Model):
('done', 'Done'),
('cancel', 'Cancelled'),
], string='Status Reserve', readonly=True, tracking=True, help="The current state of the stock picking.")
+ notee = fields.Text(string="Note")
def action_send_to_biteship(self):
url = "https://api.biteship.com/v1/orders"
@@ -193,9 +193,10 @@ class StockPicking(models.Model):
else:
raise UserError(f"Error saat mengirim ke Biteship: {response.content}")
- # @api.constrains('driver_departure_date')
- # def constrains_driver_departure_date(self):
- # self.date_doc_kirim = self.driver_departure_date
+ @api.constrains('driver_departure_date')
+ def constrains_driver_departure_date(self):
+ if not self.date_doc_kirim:
+ self.date_doc_kirim = self.driver_departure_date
@api.constrains('arrival_time')
def constrains_arrival_time(self):
@@ -279,9 +280,9 @@ class StockPicking(models.Model):
def _compute_shipping_status(self):
for rec in self:
status = 'pending'
- if rec.driver_departure_date and not rec.driver_arrival_date:
+ if rec.driver_departure_date and not (rec.sj_return_date or rec.driver_arrival_date):
status = 'shipment'
- elif rec.driver_departure_date and rec.driver_arrival_date:
+ elif rec.driver_departure_date and (rec.sj_return_date or rec.driver_arrival_date):
status = 'completed'
rec.shipping_status = status
@@ -441,26 +442,31 @@ class StockPicking(models.Model):
for pick in self:
if self.env.user.is_accounting:
pick.approval_return_status = 'approved'
- else:
- if self.picking_type_code == 'outgoing':
- if self.env.user.id in [3988, 3401, 20]:
- action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_stock_return_note_wizard')
- action['context'] = {
- 'picking_ids': [x.id for x in self]
- }
- return action
- else:
- raise UserError('Harus Sales Admin yang Ask Return')
- elif self.picking_type_code == 'incoming':
- if self.env.user.has_group('indoteknik_custom.group_role_purchasing'):
- action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_stock_return_note_wizard')
- action['context'] = {
- 'picking_ids': [x.id for x in self]
- }
- return action
- else:
- raise UserError('Harus Purchasing yang Ask Return')
+ continue
+ action = self.env['ir.actions.act_window']._for_xml_id('indoteknik_custom.action_stock_return_note_wizard')
+
+ if self.picking_type_code == 'outgoing':
+ if self.env.user.id in [3988, 3401, 20] or (
+ self.env.user.has_group('indoteknik_custom.group_role_purchasing') and 'Return of' in self.origin
+ ):
+ action['context'] = {'picking_ids': [x.id for x in self]}
+ return action
+ elif not self.env.user.has_group('indoteknik_custom.group_role_purchasing') and 'Return of' in self.origin:
+ raise UserError('Harus Purchasing yang Ask Return')
+ else:
+ raise UserError('Harus Sales Admin yang Ask Return')
+
+ elif self.picking_type_code == 'incoming':
+ if self.env.user.has_group('indoteknik_custom.group_role_purchasing') or (
+ self.env.user.id in [3988, 3401, 20] and 'Return of' in self.origin
+ ):
+ action['context'] = {'picking_ids': [x.id for x in self]}
+ return action
+ elif not self.env.user.id in [3988, 3401, 20] and 'Return of' in self.origin:
+ raise UserError('Harus Sales Admin yang Ask Return')
+ else:
+ raise UserError('Harus Purchasing yang Ask Return')
def calculate_line_no(self):
@@ -517,12 +523,31 @@ class StockPicking(models.Model):
and quant.inventory_quantity < line.product_uom_qty
):
raise UserError('Quantity reserved lebih besar dari quantity onhand di product')
+
+ def check_qty_done_stock(self):
+ for line in self.move_line_ids_without_package:
+ def check_qty_per_inventory(self, product, location):
+ quant = self.env['stock.quant'].search([
+ ('product_id', '=', product.id),
+ ('location_id', '=', location.id),
+ ])
+ if quant:
+ return quant.quantity
+
+ return 0
+
+ qty_onhand = check_qty_per_inventory(self, line.product_id, line.location_id)
+ if line.qty_done > qty_onhand:
+ raise UserError('Quantity Done melebihi Quantity Onhand')
def button_validate(self):
if not self.env.user.is_logistic_approver and self.env.context.get('active_model') == 'stock.picking':
if self.origin and 'Return of' in self.origin:
raise UserError("Button ini hanya untuk Logistik")
+
+ if self.picking_type_code == 'internal':
+ self.check_qty_done_stock()
if self._name != 'stock.picking':
return super(StockPicking, self).button_validate()
@@ -651,13 +676,13 @@ class StockPicking(models.Model):
manifest_datas = []
departure_date = self.driver_departure_date
- arrival_date = self.driver_arrival_date
+ arrival_date = self.sj_return_date if self.sj_return_date else self.driver_arrival_date
status = status_mapping.get(status_key)
if not status:
return manifest_datas
- if arrival_date:
+ if arrival_date or self.sj_return_date:
manifest_datas.append(self.create_manifest_data(status['arrival'], arrival_date))
if departure_date:
manifest_datas.append(self.create_manifest_data(status['departure'], departure_date))
@@ -684,7 +709,7 @@ class StockPicking(models.Model):
}
if not self.waybill_id or len(self.waybill_id.manifest_ids) == 0:
- response['delivered'] = self.driver_arrival_date != False
+ response['delivered'] = self.sj_return_date != False or self.driver_arrival_date != False
return response
response['delivery_order']['receiver_name'] = self.waybill_id.receiver_name
diff --git a/indoteknik_custom/models/vendor_approval.py b/indoteknik_custom/models/vendor_approval.py
index bcc5d3ea..56b81a37 100644
--- a/indoteknik_custom/models/vendor_approval.py
+++ b/indoteknik_custom/models/vendor_approval.py
@@ -32,7 +32,7 @@ class VendorApproval(models.Model):
self.order_id.vendor_approval = True
message = "Vendor Approval approved by %s" % (self.env.user.name)
self.order_id.message_post(body=message)
- if not self.order_id.due_id:
+ if not self.order_id.due_id and self.order_id.state == 'draft':
self.order_id.action_confirm()
def action_reject(self):
diff --git a/indoteknik_custom/models/wati.py b/indoteknik_custom/models/wati.py
index eed5413e..f3632334 100644
--- a/indoteknik_custom/models/wati.py
+++ b/indoteknik_custom/models/wati.py
@@ -58,41 +58,56 @@ class WatiNotification(models.Model):
return
def _create_wati_history_header(self, ticket_id, sender_name, notification_json, date_wati):
+ # Helper function to remove NUL characters
+ def remove_null_characters(value):
+ if isinstance(value, str):
+ return value.replace('\0', '')
+ return value
+
+ # Sanitize the input data
param_header = {
'ticket_id': ticket_id,
- 'conversation_id': notification_json['conversationId'],
- 'sender_name': sender_name,
- 'wa_id': notification_json['waId'],
- 'text': notification_json['text'],
- 'date_wati': date_wati or '',
+ 'conversation_id': remove_null_characters(notification_json.get('conversationId', '')),
+ 'sender_name': remove_null_characters(sender_name),
+ 'wa_id': remove_null_characters(notification_json.get('waId', '')),
+ 'text': remove_null_characters(notification_json.get('text', '')),
+ 'date_wati': remove_null_characters(date_wati or ''),
}
+
+ # Create the record
new_header = self.env['wati.history'].create([param_header])
return new_header
def _create_wati_history_line(self, new_header, ticket_id, sender_name, notification_json, date_wati):
- text_body = notification_json['text'] or ''
+ # Helper function to remove NUL characters
+ def remove_null_characters(value):
+ if isinstance(value, str):
+ return value.replace('\0', '')
+ return value
+
+ # Sanitize the input data
param_line = {
"wati_history_id": new_header.id,
- "conversation_id": notification_json['conversationId'],
- "data": notification_json['data'] or '',
- "event_type": notification_json['eventType'] or '',
- # "list_reply": notification_json['listReply'] or '',
- # "message_contact": notification_json['messageContact'] or '',
- "operator_email": notification_json['operatorEmail'] or '',
- "operator_name": notification_json['operatorName'] or '',
- "sender_name": sender_name or '',
- # "source_url": notification_json['sourceUrl'] or '',
- "status_string": notification_json['statusString'] or '',
- "text": text_body,
+ "conversation_id": remove_null_characters(notification_json.get('conversationId', '')),
+ "data": remove_null_characters(notification_json.get('data', '')),
+ "event_type": remove_null_characters(notification_json.get('eventType', '')),
+ "operator_email": remove_null_characters(notification_json.get('operatorEmail', '')),
+ "operator_name": remove_null_characters(notification_json.get('operatorName', '')),
+ "sender_name": remove_null_characters(sender_name or ''),
+ "status_string": remove_null_characters(notification_json.get('statusString', '')),
+ "text": remove_null_characters(notification_json.get('text', '')),
"ticket_id": ticket_id,
- "type": notification_json['type'] or '',
- "wa_id": notification_json['waId'] or '',
- "date_wati": date_wati or '',
+ "type": remove_null_characters(notification_json.get('type', '')),
+ "wa_id": remove_null_characters(notification_json.get('waId', '')),
+ "date_wati": remove_null_characters(date_wati or ''),
}
+
+ # Create the record safely without NUL characters
self.env['wati.history.line'].create([param_line])
- self._update_header_after_create_line(new_header, sender_name, date_wati, text_body)
+ self._update_header_after_create_line(new_header, sender_name, date_wati, param_line['text'])
return
+
def _update_header_after_create_line(self, new_header, sender_name, date_wati, text_body):
new_header.last_reply_by = sender_name
new_header.last_reply_date = date_wati
diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py
index 494f32f3..44393cf1 100644
--- a/indoteknik_custom/models/website_user_cart.py
+++ b/indoteknik_custom/models/website_user_cart.py
@@ -65,7 +65,7 @@ class WebsiteUserCart(models.Model):
if stock_quant:
res['is_in_bu'] = True
res['on_hand_qty'] = sum(stock_quant.mapped('quantity'))
- res['available_quantity'] = stock_quant.available_quantity
+ res['available_quantity'] = sum(stock_quant.mapped('available_quantity'))
else:
res['is_in_bu'] = False
res['on_hand_qty'] = 0
diff --git a/indoteknik_custom/views/partner_payment_term.xml b/indoteknik_custom/views/partner_payment_term.xml
index 433cac3e..e0f2fe39 100644
--- a/indoteknik_custom/views/partner_payment_term.xml
+++ b/indoteknik_custom/views/partner_payment_term.xml
@@ -24,6 +24,9 @@
<field name="name"/>
<field name="parent_id" readonly="1"/>
<field name="property_payment_term_id"/>
+ <field name="active_limit"/>
+ <field name="warning_stage"/>
+ <field name="blocking_stage"/>
</group>
</group>
</sheet>
diff --git a/indoteknik_custom/views/res_partner.xml b/indoteknik_custom/views/res_partner.xml
index cc6b2357..6ce340f3 100644
--- a/indoteknik_custom/views/res_partner.xml
+++ b/indoteknik_custom/views/res_partner.xml
@@ -6,6 +6,15 @@
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
+ <field name="active_limit" position="attributes">
+ <attribute name="readonly">1</attribute>
+ </field>
+ <field name="warning_stage" position="attributes">
+ <attribute name="readonly">1</attribute>
+ </field>
+ <field name="blocking_stage" position="attributes">
+ <attribute name="readonly">1</attribute>
+ </field>
<field name="npwp" position="after">
<field name="sppkp"/>
<field name="counter"/>
@@ -22,7 +31,7 @@
<field name="industry_id" position="after">
<field name="company_type_id"/>
<field name="group_partner_id"/>
- <field name="is_potential"/>
+ <field name="is_not_potential"/>
<field name="pareto_status"/>
<field name="digital_invoice_tax"/>
</field>
diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml
index b8f2d08d..3a3b1c81 100755
--- a/indoteknik_custom/views/sale_order.xml
+++ b/indoteknik_custom/views/sale_order.xml
@@ -118,8 +118,47 @@
}
</attribute>
</xpath>
+ <div name="invoice_lines" position="before">
+ <div name="vendor_id" groups="base.group_no_one" attrs="{'invisible': [('display_type', '!=', False)]}">
+ <label for="vendor_id"/>
+ <div name="vendor_id">
+ <field name="vendor_id"
+ attrs="{'readonly': [('parent.approval_status', '=', 'approved')]}"
+ domain="[('parent_id', '=', False)]"
+ options="{'no_create': True}" class="oe_inline" />
+ </div>
+ </div>
+ </div>
+
+ <div name="invoice_lines" position="before">
+ <div name="purchase_price" groups="base.group_no_one" attrs="{'invisible': [('display_type', '!=', False)]}">
+ <label for="purchase_price"/>
+ <field name="purchase_price"/>
+ </div>
+ </div>
+ <div name="invoice_lines" position="before">
+ <div name="purchase_tax_id" groups="base.group_no_one" attrs="{'invisible': [('display_type', '!=', False)]}">
+ <label for="purchase_tax_id"/>
+ <div name="purchase_tax_id">
+ <field name="purchase_tax_id"/>
+ </div>
+ </div>
+ </div>
+ <div name="invoice_lines" position="before">
+ <div name="item_percent_margin" groups="base.group_no_one" attrs="{'invisible': [('display_type', '!=', False)]}">
+ <label for="item_percent_margin"/>
+ <field name="item_percent_margin"/>
+ </div>
+ </div>
+ <div name="invoice_lines" position="before">
+ <div name="price_subtotal" groups="base.group_no_one" attrs="{'invisible': [('display_type', '!=', False)]}">
+ <label for="price_subtotal"/>
+ <field name="price_subtotal"/>
+ </div>
+ </div>
<xpath expr="//form/sheet/notebook/page/field[@name='order_line']/tree/field[@name='price_total']" position="after">
- <field name="vendor_id" attrs="{'readonly': [('parent.approval_status', '=', 'approved')]}" domain="[('parent_id', '=', False)]" options="{'no_create':True}"/>
+ <field name="qty_free_bu" optional="hide"/>
+ <field name="vendor_id" attrs="{'readonly': [('parent.approval_status', '=', 'approved')], 'invisible': [('display_type', '!=', False)]}" domain="[('parent_id', '=', False)]" options="{'no_create':True}"/>
<field name="vendor_md_id" optional="hide"/>
<field name="purchase_price" attrs="
{
diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml
index c230bc7b..1893fcaf 100644
--- a/indoteknik_custom/views/stock_picking.xml
+++ b/indoteknik_custom/views/stock_picking.xml
@@ -129,6 +129,7 @@
<page string="Delivery" name="delivery_order">
<group>
<group>
+ <field name="notee"/>
<field name="note_logistic"/>
<field name="responsible" />
<field name="carrier_id"/>