summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indoteknik_api/controllers/api_v1/sale_order.py4
-rw-r--r--indoteknik_api/models/sale_order.py2
-rw-r--r--indoteknik_custom/models/account_asset.py111
-rw-r--r--indoteknik_custom/models/automatic_purchase.py72
-rwxr-xr-xindoteknik_custom/models/sale_order.py48
-rwxr-xr-xindoteknik_custom/views/sale_order.xml2
6 files changed, 201 insertions, 38 deletions
diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py
index cff1921d..f4a2a9d4 100644
--- a/indoteknik_api/controllers/api_v1/sale_order.py
+++ b/indoteknik_api/controllers/api_v1/sale_order.py
@@ -154,13 +154,13 @@ class SaleOrder(controller.Controller):
elif status == 'belum_bayar':
domain += [
('state', '=', 'draft'),
- ('approval_status', 'in', ['pengajuan1', 'pengajuan2']),
+ ('approval_status', 'in', ['pengajuan0','pengajuan1', 'pengajuan2']),
('payment_status', 'in', [False, None, '', 'pending', 'expire'])
]
elif status == 'diproses':
domain += [
('state', '=', 'draft'),
- ('approval_status', 'in', ['pengajuan1', 'pengajuan2']),
+ ('approval_status', 'in', ['pengajuan0','pengajuan1', 'pengajuan2']),
('payment_status', '!=', False),
('payment_status', 'not in', ['', 'pending', 'expire']),
]
diff --git a/indoteknik_api/models/sale_order.py b/indoteknik_api/models/sale_order.py
index 23be358a..7951de45 100644
--- a/indoteknik_api/models/sale_order.py
+++ b/indoteknik_api/models/sale_order.py
@@ -66,7 +66,7 @@ class SaleOrder(models.Model):
elif sale_order.state == 'draft':
if not sale_order.approval_status:
data['status'] = 'draft'
- elif sale_order.approval_status in ('pengajuan1', 'pengajuan2'):
+ elif sale_order.approval_status in ('pengajuan0', 'pengajuan1', 'pengajuan2'):
if sale_order.payment_status in ('', 'pending', False, None, 'expire'):
data['status'] = 'belum_bayar'
elif sale_order.payment_status not in ['', 'pending', False, None, 'expire']:
diff --git a/indoteknik_custom/models/account_asset.py b/indoteknik_custom/models/account_asset.py
index 211ab229..c54f1d97 100644
--- a/indoteknik_custom/models/account_asset.py
+++ b/indoteknik_custom/models/account_asset.py
@@ -14,3 +14,114 @@ class AccountAsset(models.Model):
if asset.value > 0:
raise UserError("Asset masih mempunyai Value")
asset.state = 'close'
+
+ def create_move(self, post_move=True):
+ created_moves = self.env['account.move']
+ prec = self.env['decimal.precision'].precision_get('Account')
+ if self.mapped('move_id'):
+ raise UserError(_(
+ 'This depreciation is already linked to a journal entry! Please post or delete it.'))
+ for line in self:
+ category_id = line.asset_id.category_id
+ depreciation_date = self.env.context.get(
+ 'depreciation_date') or line.depreciation_date or fields.Date.context_today(
+ self)
+ company_currency = line.asset_id.company_id.currency_id
+ current_currency = line.asset_id.currency_id
+ amount = current_currency.with_context(
+ date=depreciation_date).compute(line.amount, company_currency)
+ asset_name = line.asset_id.name + ' (%s/%s)' % (
+ line.sequence, len(line.asset_id.depreciation_line_ids))
+ partner = self.env['res.partner']._find_accounting_partner(
+ line.asset_id.partner_id)
+ move_line_1 = {
+ 'name': asset_name,
+ 'account_id': category_id.account_depreciation_id.id,
+ 'debit': 0.0 if float_compare(amount, 0.0,
+ precision_digits=prec) > 0 else -amount,
+ 'credit': amount if float_compare(amount, 0.0,
+ precision_digits=prec) > 0 else 0.0,
+ 'journal_id': category_id.journal_id.id,
+ 'partner_id': partner.id,
+ 'analytic_account_id': category_id.account_analytic_id.id if category_id.type == 'sale' else False,
+ 'currency_id': company_currency != current_currency and current_currency.id or False,
+ 'amount_currency': company_currency != current_currency and - 1.0 * line.amount or 0.0,
+ }
+ move_line_2 = {
+ 'name': asset_name,
+ 'account_id': category_id.account_depreciation_expense_id.id,
+ 'credit': 0.0 if float_compare(amount, 0.0,
+ precision_digits=prec) > 0 else -amount,
+ 'debit': amount if float_compare(amount, 0.0,
+ precision_digits=prec) > 0 else 0.0,
+ 'journal_id': category_id.journal_id.id,
+ 'partner_id': partner.id,
+ 'analytic_account_id': category_id.account_analytic_id.id if category_id.type == 'purchase' else False,
+ 'currency_id': company_currency != current_currency and current_currency.id or False,
+ 'amount_currency': company_currency != current_currency and line.amount or 0.0,
+ }
+ move_vals = {
+ 'ref': line.asset_id.code,
+ 'date': depreciation_date or False,
+ 'journal_id': category_id.journal_id.id,
+ 'line_ids': [(0, 0, move_line_1), (0, 0, move_line_2)],
+ }
+ move = self.env['account.move'].create(move_vals)
+ line.write({'move_id': move.id, 'move_check': True})
+ created_moves |= move
+
+ if post_move and created_moves:
+ created_moves.filtered(lambda m: any(
+ m.asset_depreciation_ids.mapped(
+ 'asset_id.category_id.open_asset'))).post()
+ created_moves.action_post()
+ return [x.id for x in created_moves]
+
+ def create_grouped_move(self, post_move=True):
+ if not self.exists():
+ return []
+
+ created_moves = self.env['account.move']
+ category_id = self[
+ 0].asset_id.category_id # we can suppose that all lines have the same category
+ depreciation_date = self.env.context.get(
+ 'depreciation_date') or fields.Date.context_today(self)
+ amount = 0.0
+ for line in self:
+ # Sum amount of all depreciation lines
+ company_currency = line.asset_id.company_id.currency_id
+ current_currency = line.asset_id.currency_id
+ amount += current_currency.compute(line.amount, company_currency)
+
+ name = category_id.name + _(' (grouped)')
+ move_line_1 = {
+ 'name': name,
+ 'account_id': category_id.account_depreciation_id.id,
+ 'debit': 0.0,
+ 'credit': amount,
+ 'journal_id': category_id.journal_id.id,
+ 'analytic_account_id': category_id.account_analytic_id.id if category_id.type == 'sale' else False,
+ }
+ move_line_2 = {
+ 'name': name,
+ 'account_id': category_id.account_depreciation_expense_id.id,
+ 'credit': 0.0,
+ 'debit': amount,
+ 'journal_id': category_id.journal_id.id,
+ 'analytic_account_id': category_id.account_analytic_id.id if category_id.type == 'purchase' else False,
+ }
+ move_vals = {
+ 'ref': category_id.name,
+ 'date': depreciation_date or False,
+ 'journal_id': category_id.journal_id.id,
+ 'line_ids': [(0, 0, move_line_1), (0, 0, move_line_2)],
+ }
+ move = self.env['account.move'].create(move_vals)
+ self.write({'move_id': move.id, 'move_check': True})
+ created_moves |= move
+
+ if post_move and created_moves:
+ self.post_lines_and_close_asset()
+ created_moves.post()
+ created_moves.action_post()
+ return [x.id for x in created_moves] \ No newline at end of file
diff --git a/indoteknik_custom/models/automatic_purchase.py b/indoteknik_custom/models/automatic_purchase.py
index f4ecdcd6..f7c0d75e 100644
--- a/indoteknik_custom/models/automatic_purchase.py
+++ b/indoteknik_custom/models/automatic_purchase.py
@@ -314,6 +314,8 @@ class AutomaticPurchase(models.Model):
sale_ids_set = set()
sale_ids_name = set()
+ retur_cache = {}
+ incoming_cache = {}
for sale_order in matches_so:
exist = self.env['purchase.order.sales.match'].search([
('product_id', '=', sale_order.product_id.id),
@@ -324,32 +326,50 @@ class AutomaticPurchase(models.Model):
skip_line = False
- for existing in exist:
- if existing.purchase_order_id.state in ['done', 'purchase']:
- # if existing.purchase_line_id.qty_received != existing.purchase_line_id.product_qty:
- # break
-
- incoming = self.env['stock.move'].search([
- ('reference', 'ilike', 'BU/INPUT'),
- ('state', 'not in', ['done','cancel']),
- ('product_id', '=', existing.product_id.id),
- ('purchase_line_id', '=', existing.purchase_line_id.id),
- ], limit=1)
-
- if incoming:
- skip_line = True
- break
-
- retur = self.env['stock.move'].search([
- ('reference', 'ilike', 'BU/INPUT'),
- ('state', 'in', ['done']),
- ('product_id', '=', existing.product_id.id),
- ('purchase_line_id', '=', existing.purchase_line_id.id),
- ], limit=1)
-
- if retur and existing.purchase_line_id.qty_received == existing.purchase_line_id.product_qty:
- skip_line = True
- break
+ sale_line_id = sale_order.sale_line_id.id
+
+ if sale_line_id not in incoming_cache:
+
+ qty_incoming = 0
+
+ for existing in exist:
+ if existing.purchase_order_id.state in ['done', 'purchase']:
+
+ incoming_moves = self.env['stock.move'].search([
+ ('reference', 'ilike', 'BU/INPUT'),
+ ('state', 'not in', ['done','cancel']),
+ ('product_id', '=', existing.product_id.id),
+ ('purchase_line_id', '=', existing.purchase_line_id.id),
+ ])
+
+ qty_incoming += sum(incoming_moves.mapped('product_uom_qty'))
+
+ incoming_cache[sale_line_id] = qty_incoming
+
+
+ qty_need = sale_order.sale_line_id.product_uom_qty
+
+ if incoming_cache[sale_line_id] >= qty_need:
+ skip_line = True
+
+ sale_line_id = sale_order.sale_line_id.id
+
+ if sale_line_id not in retur_cache:
+
+ fully_received = True
+
+ for existing in exist:
+ if existing.purchase_order_id.state in ['done', 'purchase']:
+
+ if existing.purchase_line_id.qty_received != existing.purchase_line_id.product_qty:
+ fully_received = False
+ break
+
+ retur_cache[sale_line_id] = fully_received
+
+
+ if retur_cache[sale_line_id] and exist:
+ skip_line = True
if skip_line:
continue
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py
index d42aefcc..0cb6670e 100755
--- a/indoteknik_custom/models/sale_order.py
+++ b/indoteknik_custom/models/sale_order.py
@@ -156,6 +156,7 @@ class SaleOrder(models.Model):
total_margin_excl_third_party = fields.Float('Before Margin', help="Before Margin in Sales Order Header")
approval_status = fields.Selection([
+ ('pengajuan0', 'Approval Team Sales'),
('pengajuan1', 'Approval Manager'),
('pengajuan2', 'Approval Pimpinan'),
('approved', 'Approved'),
@@ -2384,8 +2385,15 @@ class SaleOrder(models.Model):
# 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')
-
- if order._requires_approval_margin_leader():
+ value_trigger = order._requires_approval_by_value()
+ if value_trigger:
+ self.check_product_bom()
+ self.check_credit_limit()
+ self.check_limit_so_to_invoice()
+ order.approval_status = 'pengajuan0'
+ order.message_post(body="Mengajukan approval ke Team Sales_")
+ return self._create_approval_notification('Team Sales')
+ elif order._requires_approval_margin_leader():
order.approval_status = 'pengajuan2'
order.message_post(body="Mengajukan approval ke Pimpinan")
return self._create_approval_notification('Pimpinan')
@@ -2400,9 +2408,16 @@ class SaleOrder(models.Model):
self.check_product_bom()
self.check_credit_limit()
self.check_limit_so_to_invoice()
- order.approval_status = 'pengajuan1'
+ order.approval_status = 'pengajuan0'
order.message_post(body="Mengajukan approval ke Team Sales")
return self._create_approval_notification('Team Sales')
+ # elif value_trigger:
+ # self.check_product_bom()
+ # self.check_credit_limit()
+ # self.check_limit_so_to_invoice()
+ # order.approval_status = 'pengajuan0'
+ # order.message_post(body="Mengajukan approval ke Team Sales_")
+ # return self._create_approval_notification('Team Sales')
if not order.with_context(ask_approval=True)._is_request_to_own_team_leader():
return self._create_notification_action(
@@ -2667,16 +2682,25 @@ class SaleOrder(models.Model):
'Warning',
'Hanya bisa konfirmasi SO tim Anda.'
)
- if order._requires_approval_margin_leader():
+ value_trigger = order._requires_approval_by_value()
+ if value_trigger:
+ order.approval_status = 'pengajuan0'
+ order.message_post(body="Mengajukan approval ke Team Sales")
+ return self._create_approval_notification('Team Sales')
+ elif order._requires_approval_margin_leader():
order.approval_status = 'pengajuan2'
return self._create_approval_notification('Pimpinan')
elif order._requires_approval_margin_manager():
order.approval_status = 'pengajuan1'
return self._create_approval_notification('Sales Manager')
- elif order._requires_approval_team_sales():
- order.approval_status = 'pengajuan1'
+ elif value_trigger or order._requires_approval_team_sales():
+ order.approval_status = 'pengajuan0'
order.message_post(body="Mengajukan approval ke Team Sales")
return self._create_approval_notification('Team Sales')
+ # elif value_trigger:
+ # order.approval_status = 'pengajuan0'
+ # order.message_post(body="Mengajukan approval ke Team Sales (Total SO > 50jt)")
+ # return self._create_approval_notification('Team Sales')
order.approval_status = 'approved'
order._set_sppkp_npwp_contact()
@@ -2788,7 +2812,15 @@ class SaleOrder(models.Model):
and not self.env.user.is_leader
)
-
+ def _requires_approval_by_value(self):
+ # LIMIT_VALUE = 50000000
+ LIMIT_VALUE = float(self.env['ir.config_parameter'].sudo().get_param('so.limit_value_approve', default='50000000'))
+ return (
+ self.amount_total >= LIMIT_VALUE
+ and self.env.user.id not in [11, 9, 375] # Eko, Ade, Putra
+ and not self.env.user.is_sales_manager
+ and not self.env.user.is_leader
+ )
def _is_request_to_own_team_leader(self):
user = self.env.user
@@ -3407,7 +3439,7 @@ class SaleOrder(models.Model):
#payment term vals
if 'payment_term_id' in vals and any(
- order.approval_status in ['pengajuan1', 'pengajuan2', 'approved'] for order in self):
+ order.approval_status in ['pengajuan0','pengajuan1', 'pengajuan2', 'approved'] for order in self):
raise UserError(
"Payment Term tidak dapat diubah karena Sales Order sedang dalam proses approval atau sudah diapprove.")
diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml
index c3df92ec..2d4488ab 100755
--- a/indoteknik_custom/views/sale_order.xml
+++ b/indoteknik_custom/views/sale_order.xml
@@ -385,7 +385,7 @@
{
'readonly': [
'|',
- ('approval_status', 'in', ['pengajuan1', 'pengajuan2', 'approved']),
+ ('approval_status', 'in', ['pengajuan0','pengajuan1', 'pengajuan2', 'approved']),
('state', 'not in', ['cancel', 'draft'])
]
}