summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2024-10-16 15:47:07 +0700
committerstephanchrst <stephanchrst@gmail.com>2024-10-16 15:47:07 +0700
commit8914f55dba0a2d4a1e992c9d0635ae993950bcf1 (patch)
treef41be6b8474db4f61e0122c68614a191829e39cf
parentd7f4569c5d2dcda1316ca4ef37fed53f467df9df (diff)
parenta1b2542ebc2d527d07edbcbaab467152a46f1d33 (diff)
Merge branch 'production' into feature/generate_url
-rw-r--r--indoteknik_api/controllers/api_v1/product.py1
-rw-r--r--indoteknik_api/controllers/api_v1/user.py2
-rw-r--r--indoteknik_custom/models/approval_unreserve.py7
-rwxr-xr-xindoteknik_custom/models/crm_lead.py91
-rwxr-xr-xindoteknik_custom/models/purchase_order.py10
-rw-r--r--indoteknik_custom/models/report_stock_forecasted.py1
-rwxr-xr-xindoteknik_custom/models/sale_order.py22
-rw-r--r--indoteknik_custom/models/stock_picking.py24
-rwxr-xr-xindoteknik_custom/views/sale_order.xml4
-rw-r--r--indoteknik_custom/views/stock_picking.xml1
10 files changed, 147 insertions, 16 deletions
diff --git a/indoteknik_api/controllers/api_v1/product.py b/indoteknik_api/controllers/api_v1/product.py
index e779e623..9673b3ef 100644
--- a/indoteknik_api/controllers/api_v1/product.py
+++ b/indoteknik_api/controllers/api_v1/product.py
@@ -74,7 +74,6 @@ class Product(controller.Controller):
if qty_available > 0:
qty = qty_available + total_adem + total_excell
- sla_date = '1 Hari'
elif qty_altama > 0 or qty_vendor > 0:
qty = total_adem if qty_altama > 0 else total_excell
sla_date = '2-4 Hari'
diff --git a/indoteknik_api/controllers/api_v1/user.py b/indoteknik_api/controllers/api_v1/user.py
index c7bfe91a..e4f8b97f 100644
--- a/indoteknik_api/controllers/api_v1/user.py
+++ b/indoteknik_api/controllers/api_v1/user.py
@@ -248,7 +248,7 @@ class User(controller.Controller):
if type_acc == 'individu':
user.partner_id.customer_type = 'nonpkp'
- user.partner_id.npwp = '0.000.000.0-000.000'
+ user.partner_id.npwp = '00.000.000.0-000.000'
user.partner_id.sppkp = '-'
user.partner_id.nama_wajib_pajak = name
user.partner_id.user_id = 3222
diff --git a/indoteknik_custom/models/approval_unreserve.py b/indoteknik_custom/models/approval_unreserve.py
index 88409c37..07ddda1f 100644
--- a/indoteknik_custom/models/approval_unreserve.py
+++ b/indoteknik_custom/models/approval_unreserve.py
@@ -31,12 +31,12 @@ class ApprovalUnreserve(models.Model):
if not self.picking_id:
raise ValidationError("Picking is required")
- stock_move = self.env['stock.move'].search([('picking_id', '=', self.picking_id.id), ('state', '=', 'assigned')])
+ stock_move = self.env['stock.move'].search([('picking_id', '=', self.picking_id.id), ('state', 'in', ['assigned', 'partially_available'])])
if not stock_move:
raise ValidationError("Picking is not found")
- for move in stock_move:
+ for move in stock_move:
self.approval_line.create({
'approval_id': self.id,
'move_id': move.id
@@ -68,7 +68,7 @@ class ApprovalUnreserve(models.Model):
if not move:
raise UserError("Product tidak ada di destination picking")
- qty_unreserve = line.unreserve_qty + move.forecast_availability
+ qty_unreserve = line.unreserve_qty + move.reserved_availability
if move.product_uom_qty < qty_unreserve:
raise UserError("Quantity yang di unreserve melebihi quantity yang ada")
@@ -86,6 +86,7 @@ class ApprovalUnreserve(models.Model):
})
# Trigger the unreserve function
self._trigger_unreserve()
+ 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/crm_lead.py b/indoteknik_custom/models/crm_lead.py
index 9ffd607c..de2bdb12 100755
--- a/indoteknik_custom/models/crm_lead.py
+++ b/indoteknik_custom/models/crm_lead.py
@@ -2,6 +2,7 @@ from odoo import fields, models, api
import logging
import random
from odoo.exceptions import AccessError, UserError, ValidationError
+from datetime import datetime, timedelta
_logger = logging.getLogger(__name__)
@@ -97,4 +98,92 @@ class CrmLead(models.Model):
lead.user_id = salesperson_id
-
+ def _update_pipeline(self, delta=48, limit=100):
+ # Get the current time
+ current_time = datetime.now()
+
+ # Calculate the time 24 hours ago
+ time_48_hours_ago = current_time - timedelta(hours=delta)
+
+ # Define the allowed states
+ allowed_states = ['sale', 'done']
+
+ # Search for sale orders with date_order greater than 24 hours ago and opportunity_id is null
+ orders = self.env['sale.order'].search([
+ ('write_date', '>=', time_48_hours_ago),
+ ('opportunity_id', '!=', False),
+ ('state', 'in', allowed_states)
+ ], limit=limit)
+ for order in orders:
+ order.opportunity_id.stage_id = 4
+ _logger.info('finish order stage pipeline %s' % order.id)
+
+ def _cancel_pipeline(self, delta=48, limit=100):
+ # Get the current time
+ current_time = datetime.now()
+
+ # Calculate the time 24 hours ago
+ time_48_hours_ago = current_time - timedelta(hours=delta)
+
+ # Define the allowed states
+ allowed_states = ['cancel']
+
+ # Search for sale orders with date_order greater than 24 hours ago and opportunity_id is null
+ orders = self.env['sale.order'].search([
+ ('write_date', '>=', time_48_hours_ago),
+ ('opportunity_id', '!=', False),
+ ('state', 'in', allowed_states)
+ ], limit=limit)
+ for order in orders:
+ order.opportunity_id.stage_id = 7
+ _logger.info('cancel order stage pipeline %s' % order.id)
+
+ def _convert_to_pipeline(self, delta=48, limit=100):
+ # Get the current time
+ current_time = datetime.now()
+
+ # Calculate the time 24 hours ago
+ time_48_hours_ago = current_time - timedelta(hours=delta)
+
+ # Define the allowed states
+ allowed_states = ['draft', 'done', 'sale', 'sent', 'cancel']
+
+ # Search for sale orders with date_order greater than 24 hours ago and opportunity_id is null
+ orders = self.env['sale.order'].search([
+ ('write_date', '>=', time_48_hours_ago),
+ ('opportunity_id', '=', False),
+ ('state', 'in', allowed_states)
+ ], limit=limit)
+ # stage
+ # 1 potensi baru, 2 proses quotation, 3 proses lain visit, 4 proses berhasil, 5 proses negosiasi, 7 tidak terpakai / gagal
+ for order in orders:
+ # stage_id = 2
+ if order.state == 'sale' or order.state == 'done':
+ stage_id = 4
+ elif order.state == 'sent':
+ stage_id = 5
+ elif order.state == 'cancel':
+ stage_id = 7
+ else:
+ stage_id = 2
+ crm_lead = self.env['crm.lead'].create([{
+ 'email_normalized': order.email,
+ 'name': order.name,
+ 'user_id': order.user_id.id,
+ 'company_id': 1,
+ 'type': 'opportunity',
+ 'priority': 0,
+ 'team_id': order.team_id.id,
+ 'stage_id': stage_id,
+ 'expected_revenue': order.amount_untaxed,
+ 'partner_id': order.partner_id.parent_id.id or order.partner_id.id,
+ 'contact_name': order.partner_id.name,
+ 'partner_name': order.partner_id.parent_id.name or order.partner_id.name,
+ 'phone': order.partner_id.mobile,
+ 'street': order.partner_id.street,
+ 'street2': order.partner_id.street2,
+ 'zip': order.partner_id.zip,
+ 'order_id': order.id
+ }])
+ order.opportunity_id = crm_lead.id
+ _logger.info('convert order to opportunity %s' % crm_lead.id)
diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py
index 340df49e..f8af409f 100755
--- a/indoteknik_custom/models/purchase_order.py
+++ b/indoteknik_custom/models/purchase_order.py
@@ -508,11 +508,11 @@ class PurchaseOrder(models.Model):
if self.amount_untaxed >= 50000000 and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'):
raise UserError("Hanya Merchandiser yang bisa approve")
- if self.total_percent_margin < self.total_so_percent_margin and not self.env.user.is_purchasing_manager and not self.env.user.is_leader:
- raise UserError("Beda Margin dengan Sales, harus approval Manager")
+ if self.total_percent_margin < self.total_so_percent_margin and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader:
+ raise UserError("Beda Margin dengan Sales, harus approval Merchandise")
if not self.from_apo:
- if not self.sale_order_id and not self.env.user.is_purchasing_manager and not self.env.user.is_leader:
- raise UserError("Tidak ada link dengan SO, harus approval Manager")
+ if not self.sale_order_id and self.env.user.has_group('indoteknik_custom.group_role_merchandiser') and not self.env.user.is_leader:
+ raise UserError("Tidak ada link dengan SO, harus approval Merchandise")
send_email = False
self.add_product_to_pricelist()
@@ -641,7 +641,7 @@ class PurchaseOrder(models.Model):
def po_approve(self):
if self.amount_untaxed >= 50000000 and not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'):
raise UserError("Hanya Merchandiser yang bisa approve")
- if self.env.user.is_leader or self.env.user.is_purchasing_manager:
+ if 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.sale_order_id:
raise UserError("Bisa langsung Confirm")
diff --git a/indoteknik_custom/models/report_stock_forecasted.py b/indoteknik_custom/models/report_stock_forecasted.py
index 5f9427f8..ebdc7d4a 100644
--- a/indoteknik_custom/models/report_stock_forecasted.py
+++ b/indoteknik_custom/models/report_stock_forecasted.py
@@ -33,7 +33,6 @@ class ReplenishmentReport(models.AbstractModel):
'reserved_from': result,
'qty_fullfillment': quantity,
})
-
return lines
def _calculate_result(self, line):
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py
index c1c2c267..22130ac3 100755
--- a/indoteknik_custom/models/sale_order.py
+++ b/indoteknik_custom/models/sale_order.py
@@ -136,6 +136,12 @@ class SaleOrder(models.Model):
domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", tracking=True)
total_weight = fields.Float(string='Total Weight', compute='_compute_total_weight')
+ pareto_status = fields.Selection([
+ ('PR', 'Pareto Repeating'),
+ ('PPR', 'Potensi Pareto Repeating'),
+ ('PNR', 'Pareto Non Repeating'),
+ ('NP', 'Non Pareto')
+ ])
def _compute_total_weight(self):
total_weight = 0
@@ -642,6 +648,7 @@ class SaleOrder(models.Model):
self.sppkp = parent_id.sppkp
self.customer_type = parent_id.customer_type
self.email = parent_id.email
+ self.pareto_status = parent_id.pareto_status
@api.onchange('partner_id')
def onchange_partner_id(self):
@@ -1024,11 +1031,20 @@ class SaleOrder(models.Model):
def _set_sppkp_npwp_contact(self):
partner = self.partner_id.parent_id or self.partner_id
- if not partner.sppkp or not partner.npwp or not partner.email or partner.customer_type:
- partner.customer_type = self.customer_type
- partner.npwp = self.npwp
+ if not partner.sppkp:
partner.sppkp = self.sppkp
+ if not partner.npwp:
+ partner.npwp = self.npwp
+ if not partner.email:
partner.email = self.email
+ if not partner.customer_type:
+ partner.customer_type = self.customer_type
+
+ # if not partner.sppkp or not partner.npwp or not partner.email or partner.customer_type:
+ # partner.customer_type = self.customer_type
+ # partner.npwp = self.npwp
+ # partner.sppkp = self.sppkp
+ # partner.email = self.email
def _compute_total_margin(self):
for order in self:
diff --git a/indoteknik_custom/models/stock_picking.py b/indoteknik_custom/models/stock_picking.py
index 14190474..1b2baea7 100644
--- a/indoteknik_custom/models/stock_picking.py
+++ b/indoteknik_custom/models/stock_picking.py
@@ -101,6 +101,13 @@ class StockPicking(models.Model):
('no', 'Nothing to Invoice')
], string='Invoice Status', related="sale_id.invoice_status")
+ state_reserve = fields.Selection([
+ ('waiting', 'Waiting For Fullfilment'),
+ ('ready', 'Ready to Ship'),
+ ('done', 'Done'),
+ ('cancel', 'Cancelled'),
+ ], string='Status Reserve', readonly=True, tracking=True, help="The current state of the stock picking.")
+
@api.constrains('driver_departure_date')
def constrains_driver_departure_date(self):
self.date_doc_kirim = self.driver_departure_date
@@ -134,9 +141,24 @@ class StockPicking(models.Model):
res = super(StockPicking, self).do_unreserve()
current_time = datetime.datetime.utcnow()
self.date_unreserve = current_time
+ # self.check_state_reserve()
return res
+ def check_state_reserve(self):
+ do = self.search([
+ ('state', 'not in', ['cancel', 'draft', 'done']),
+ ('picking_type_code', '=', 'outgoing')
+ ])
+
+ for rec in do:
+ rec.state_reserve = 'ready'
+
+ for line in rec.move_ids_without_package:
+ if line.product_uom_qty > line.reserved_availability:
+ rec.state_reserve = 'waiting'
+ break
+
def _create_approval_notification(self, approval_role):
title = 'Warning'
message = f'Butuh approval sales untuk unreserved'
@@ -275,6 +297,7 @@ class StockPicking(models.Model):
current_time = datetime.datetime.utcnow()
self.real_shipping_id = self.sale_id.real_shipping_id
self.date_availability = current_time
+ # self.check_state_reserve()
return res
def ask_approval(self):
@@ -421,6 +444,7 @@ class StockPicking(models.Model):
res = super(StockPicking, self).button_validate()
self.calculate_line_no()
self.date_done = datetime.datetime.utcnow()
+ self.state_reserve = 'done'
return res
@api.model
diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml
index 895b242c..98001589 100755
--- a/indoteknik_custom/views/sale_order.xml
+++ b/indoteknik_custom/views/sale_order.xml
@@ -73,6 +73,7 @@
<field name="margin_after_delivery_purchase"/>
<field name="percent_margin_after_delivery_purchase"/>
<field name="total_weight"/>
+ <field name="pareto_status"/>
</field>
<field name="analytic_account_id" position="after">
<field name="customer_type" required="1"/>
@@ -140,7 +141,6 @@
<field name="weight" optional="hide"/>
<field name="amount_voucher_disc" string="Voucher" readonly="1" optional="hide"/>
<field name="order_promotion_id" string="Promotion" readonly="1" optional="hide"/>
- <field name="md_vendor_id" string="MD Vendor" readonly="1" optional="hide"/>
</xpath>
<xpath expr="//form/sheet/notebook/page/field[@name='order_line']/tree/field[@name='product_id']" position="before">
<field name="line_no" readonly="1" optional="hide"/>
@@ -245,6 +245,7 @@
<field name="client_order_ref"/>
<field name="payment_type" optional="hide"/>
<field name="payment_status" optional="hide"/>
+ <field name="pareto_status" optional="hide"/>
</field>
</field>
</record>
@@ -263,6 +264,7 @@
<field name="date_driver_arrival"/>
<field name="payment_type" optional="hide"/>
<field name="payment_status" optional="hide"/>
+ <field name="pareto_status" optional="hide"/>
</field>
</field>
</record>
diff --git a/indoteknik_custom/views/stock_picking.xml b/indoteknik_custom/views/stock_picking.xml
index 899d29eb..af1af563 100644
--- a/indoteknik_custom/views/stock_picking.xml
+++ b/indoteknik_custom/views/stock_picking.xml
@@ -16,6 +16,7 @@
<field name="driver_arrival_date" optional="hide"/>
<field name="note_logistic" optional="hide"/>
<field name="note" optional="hide"/>
+ <field name="state_reserve" optional="hide"/>
</field>
<field name="partner_id" position="after">
<field name="purchase_representative_id"/>