summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAzka Nathan <darizkyfaz@gmail.com>2024-10-04 14:23:59 +0700
committerAzka Nathan <darizkyfaz@gmail.com>2024-10-04 14:23:59 +0700
commit48c220d1c38f435962b8b630c5209ba781ca30df (patch)
tree628b39f7c40793b2029aa2267f9ea5af4f580ee0
parent7059f095dd09649f7c12f74ff29200f644bbc854 (diff)
push
-rwxr-xr-xindoteknik_custom/models/sale_order.py71
-rw-r--r--indoteknik_custom/models/sale_order_line.py8
-rw-r--r--indoteknik_custom/models/vendor_approval.py28
-rw-r--r--indoteknik_custom/models/website_user_cart.py2
-rw-r--r--indoteknik_custom/views/ir_sequence.xml10
-rwxr-xr-xindoteknik_custom/views/sale_order.xml9
-rw-r--r--indoteknik_custom/views/vendor_approval.xml16
7 files changed, 110 insertions, 34 deletions
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py
index a6ea6c81..0f22a7d4 100755
--- a/indoteknik_custom/models/sale_order.py
+++ b/indoteknik_custom/models/sale_order.py
@@ -135,6 +135,12 @@ class SaleOrder(models.Model):
'account.payment.term', string='Payment Terms', check_company=True, # Unrequired company
domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", tracking=True)
+ total_weight = fields.Float(string='Total Weight', compute='_compute_total_weight')
+
+ def _compute_total_weight(self):
+ for order in self:
+ order.total_weight = sum(line.weight for line in order.order_line)
+
def action_estimate_shipping(self):
total_weight = 0
missing_weight_products = []
@@ -155,38 +161,45 @@ class SaleOrder(models.Model):
# Mendapatkan city_id berdasarkan nama kota
origin_city_name = self.warehouse_id.partner_id.kota_id.name
- destination_city_name = self.real_shipping_id.kota_id.name
- origin_subdistrict_name = self.warehouse_id.partner_id.kecamatan_id.name
- destination_subdistrict_name = self.real_shipping_id.kecamatan_id.name
+ destination_subsdistrict_id = self.real_shipping_id.kecamatan_id.rajaongkir_id
- origin_id_city = self._get_city_id_by_name(origin_city_name)
- destination_id_city = self._get_city_id_by_name(destination_city_name)
- origin_city_id = self._get_subdistrict_id_by_name(origin_id_city, origin_subdistrict_name)
- destination_city_id = self._get_subdistrict_id_by_name(destination_id_city, destination_subdistrict_name)
-
- if not origin_city_id or not destination_city_id:
+ if not destination_subsdistrict_id:
raise UserError("Gagal mendapatkan ID kota asal atau tujuan.")
- result = self._call_rajaongkir_api(total_weight, origin_city_id, destination_city_id)
+ result = self._call_rajaongkir_api(total_weight, destination_subsdistrict_id)
if result:
estimated_cost = result['rajaongkir']['results'][0]['costs'][0]['cost'][0]['value']
self.delivery_amt = estimated_cost
- self.message_post(body=f"Estimasi Ongkos Kirim: {self.delivery_amt}")
+ shipping_info = []
+ for courier in result['rajaongkir']['results']:
+ for cost_detail in courier['costs']:
+ service = cost_detail['service']
+ description = cost_detail['description']
+ etd = cost_detail['cost'][0]['etd']
+ value = cost_detail['cost'][0]['value']
+ shipping_info.append(f"Service: {service}, Description: {description}, ETD: {etd} hari, Cost: Rp {value}")
+
+ log_message = "<br/>".join(shipping_info)
+
+ description_ongkir = result['rajaongkir']['results'][0]['costs'][0]['description']
+ etd_ongkir = result['rajaongkir']['results'][0]['costs'][0]['cost'][0]['etd']
+ service_ongkir = result['rajaongkir']['results'][0]['costs'][0]['service']
+ self.message_post(body=f"Estimasi Ongkos Kirim: Rp{self.delivery_amt}<br/>Service: {service_ongkir}<br/>Description: {description_ongkir}<br/>ETD: {etd_ongkir}<br/>Detail Lain:<br/>{log_message}")
else:
raise UserError("Gagal mendapatkan estimasi ongkir.")
- def _call_rajaongkir_api(self, total_weight, origin_city_id, destination_city_id):
+ def _call_rajaongkir_api(self, total_weight, destination_subsdistrict_id):
url = 'https://pro.rajaongkir.com/api/cost'
headers = {
- 'key': '7ac9883688da043b50cc32f0e3070bb6',
+ 'key': '9b1310f644056d84d60b0af6bb21611a',
}
courier = self.carrier_id.name.lower()
data = {
- 'origin': int(origin_city_id),
+ 'origin': 2127,
'originType': 'subdistrict',
- 'destination': int(destination_city_id),
+ 'destination': int(destination_subsdistrict_id),
'destinationType': 'subdistrict',
'weight': int(total_weight * 1000),
'courier': courier,
@@ -212,7 +225,7 @@ class SaleOrder(models.Model):
def _get_city_id_by_name(self, city_name):
url = 'https://pro.rajaongkir.com/api/city'
headers = {
- 'key': '7ac9883688da043b50cc32f0e3070bb6',
+ 'key': '9b1310f644056d84d60b0af6bb21611a',
}
normalized_city_name = self._normalize_city_name(city_name)
@@ -228,14 +241,17 @@ class SaleOrder(models.Model):
def _get_subdistrict_id_by_name(self, city_id, subdistrict_name):
url = f'https://pro.rajaongkir.com/api/subdistrict?city={city_id}'
headers = {
- 'key': '7ac9883688da043b50cc32f0e3070bb6',
+ 'key': '9b1310f644056d84d60b0af6bb21611a',
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
subdistrict_data = response.json()
for subdistrict in subdistrict_data['rajaongkir']['results']:
- if subdistrict['subdistrict_name'].lower() == subdistrict_name.lower():
+ subsdistrict_1 = subdistrict['subdistrict_name'].lower()
+ subsdistrict_2 = subdistrict_name.lower()
+
+ if subsdistrict_1 == subsdistrict_2:
return subdistrict['subdistrict_id']
return None
@@ -808,14 +824,24 @@ class SaleOrder(models.Model):
def validate_different_vendor(self):
different_vendor = self.order_line.filtered(lambda l: l.vendor_id and l.vendor_md_id and l.vendor_id.id != l.vendor_md_id.id)
+
+ if self.vendor_approval_id and self.vendor_approval_id.state == 'draft':
+ raise UserError('SO ini sedang dalam review Vendor Approval')
+
+ if self.vendor_approval_id and self.vendor_approval_id.state == 'cancel':
+ raise UserError('Vendor Approval SO ini Di Reject')
+
if different_vendor:
vendor_approval = self.env['vendor.approval'].create({
'order_id': self.id,
+ 'create_date_so': self.create_date,
+ 'partner_id': self.partner_id.id,
'state': 'draft',
})
self.vendor_approval_id = vendor_approval.id
- for line in self.line:
+
+ for line in different_vendor:
self.env['vendor.approval.line'].create({
'vendor_approval_id': vendor_approval.id,
'product_id': line.product_id.id,
@@ -824,11 +850,18 @@ class SaleOrder(models.Model):
'vendor_md_id': line.vendor_md_id.id,
'purchase_price': line.purchase_price,
'purchase_price_md': line.purchase_price_md,
+ 'sales_price': line.price_unit,
+ 'margin_before': line.margin_md,
+ 'margin_after': line.item_percent_margin,
+ 'purchase_tax_id': line.purchase_tax_id.id,
+ 'sales_tax_id': line.tax_id[0].id if line.tax_id else False,
+ 'percent_margin_difference': (line.price_unit - line.purchase_price_md) / line.purchase_price_md if line.purchase_price_md else False,
})
return True
else:
return False
+
def action_confirm(self):
for order in self:
diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py
index 06b0f53d..98a6c759 100644
--- a/indoteknik_custom/models/sale_order_line.py
+++ b/indoteknik_custom/models/sale_order_line.py
@@ -34,6 +34,7 @@ class SaleOrderLine(models.Model):
reserved_from = fields.Char(string='Reserved From', copy=False)
item_percent_margin_without_deduction = fields.Float('%Margin', compute='_compute_item_margin_without_deduction')
weight = fields.Float(string='Weight')
+ margin_md = fields.Float(string='Margin MD')
@api.constrains('note_procurement')
def note_procurement_to_apo(self):
@@ -127,6 +128,9 @@ class SaleOrderLine(models.Model):
else:
line.item_percent_margin = 0
+ if not line.margin_md:
+ line.margin_md = line.item_percent_margin
+
@api.onchange('vendor_id')
def onchange_vendor_id(self):
# TODO : need to change this logic @stephan
@@ -135,7 +139,6 @@ class SaleOrderLine(models.Model):
elif self.product_id.categ_id.id == 34: # finish good / manufacturing only
cost = self.product_id.standard_price
self.purchase_price = cost
- self.purchase_price_md = cost
elif self.product_id.x_manufacture.override_vendor_id:
# purchase_price = self.env['purchase.pricelist'].search(
# [('vendor_id', '=', self.product_id.x_manufacture.override_vendor_id.id),
@@ -143,8 +146,6 @@ class SaleOrderLine(models.Model):
# limit=1, order='count_trx_po desc, count_trx_po_vendor desc')
price, taxes, vendor_id = self._get_purchase_price_by_vendor(self.product_id, self.vendor_id)
self.purchase_price = price
- self.purchase_price_md = price
- self.vendor_md_id = self.vendor_id
self.purchase_tax_id = taxes
# else:
# purchase_price = self.env['purchase.pricelist'].search(
@@ -251,6 +252,7 @@ class SaleOrderLine(models.Model):
price, taxes, vendor_id = self._get_purchase_price(line.product_id)
line.vendor_id = vendor_id
line.vendor_md_id = vendor_id
+ line.margin_md = line.item_percent_margin
line.tax_id = line.order_id.sales_tax_id
# price, taxes = line._get_valid_purchase_price(purchase_price)
line.purchase_price = price
diff --git a/indoteknik_custom/models/vendor_approval.py b/indoteknik_custom/models/vendor_approval.py
index 442aec7a..e540b8fc 100644
--- a/indoteknik_custom/models/vendor_approval.py
+++ b/indoteknik_custom/models/vendor_approval.py
@@ -15,21 +15,35 @@ class VendorApproval(models.Model):
partner_id = fields.Many2one('res.partner', string="Customer", readonly=True)
order_id = fields.Many2one('sale.order', string="SO", readonly=True)
vendor_approval_line = fields.One2many('vendor.approval.line', 'vendor_approval_id', string='Vendor Approval Lines', auto_join=True)
- state = fields.Selection([('draft', 'Draft'), ('done', 'Done'), ('cancel', 'Cancel')], string='State', tracking=True)
+ state = fields.Selection([('draft', 'Draft'), ('done', 'Done'), ('cancel', 'Reject')], string='State', tracking=True)
+ create_date_so = fields.Datetime(string='Create Date SO', readonly=True)
+
+ @api.model
+ def create(self, vals):
+ vals['number'] = self.env['ir.sequence'].next_by_code('vendor.approval') or '0'
+ result = super(VendorApproval, self).create(vals)
+ return result
def action_approve(self):
if not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'):
raise UserError('Hanya Merchandiser yang bisa approve')
+
self.state = 'done'
self.order_id.update({'vendor_approval': True})
self.order_id.action_confirm()
+ message = "Vendor Approval approved by %s" % (self.env.user.name)
+ self.order_id.message_post(body=message)
+
-
def action_reject(self):
if not self.env.user.has_group('indoteknik_custom.group_role_merchandiser'):
raise UserError('Hanya Merchandiser yang bisa cancel')
+
self.state = 'cancel'
+ message = "Vendor Approval rejected by %s" % (self.env.user.name)
+ self.order_id.message_post(body=message)
+
def unlink(self):
res = super(VendorApproval, self).unlink()
if not self._name == 'vendor.approval':
@@ -47,7 +61,13 @@ class VendorApprovalLine(models.Model):
product_uom_qty = fields.Float(string='Quantity')
vendor_id = fields.Many2one('res.partner', string='Vendor')
vendor_md_id = fields.Many2one('res.partner', string='Vendor MD')
- purchase_price = fields.Many2one(string='Purchase Price')
- purchase_price_md= fields.Many2one(string='Purchase Price MD')
+ sales_price = fields.Float(string='Sales Price')
+ margin_before = fields.Float(string='Margin Before')
+ margin_after = fields.Float(string='Margin After')
+ purchase_price = fields.Float(string='Purchase Price')
+ purchase_price_md= fields.Float(string='Purchase Price MD')
+ purchase_tax_id = fields.Many2one('account.tax', string='Purchase Tax', domain=['|', ('active', '=', False), ('active', '=', True)])
+ sales_tax_id = fields.Many2one('account.tax', string='Sales Tax', domain=['|', ('active', '=', False), ('active', '=', True)])
+ percent_margin_difference = fields.Float(string='Percent Margin Difference')
diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py
index 169f4a6b..8a321187 100644
--- a/indoteknik_custom/models/website_user_cart.py
+++ b/indoteknik_custom/models/website_user_cart.py
@@ -173,7 +173,7 @@ class WebsiteUserCart(models.Model):
}
return result
- def action_mail_reminder_to_checkout(self, limit=10):
+ def action_mail_reminder_to_checkout(self, limit=250):
user_ids = self.search([]).mapped('user_id')[:limit]
for user in user_ids:
diff --git a/indoteknik_custom/views/ir_sequence.xml b/indoteknik_custom/views/ir_sequence.xml
index dd501d8c..dfb56100 100644
--- a/indoteknik_custom/views/ir_sequence.xml
+++ b/indoteknik_custom/views/ir_sequence.xml
@@ -21,6 +21,16 @@
<field name="number_increment">1</field>
</record>
+ <record id="sequence_vendor_approval" model="ir.sequence">
+ <field name="name">Vendor Approval</field>
+ <field name="code">vendor.approval</field>
+ <field name="active">TRUE</field>
+ <field name="prefix">VA/%(year)s/</field>
+ <field name="padding">5</field>
+ <field name="number_next">1</field>
+ <field name="number_increment">1</field>
+ </record>
+
<record id="sequence_approval_unreserve" model="ir.sequence">
<field name="name">Approval Unreserve</field>
<field name="code">approval.unreserve</field>
diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml
index f2a57fc7..9a637441 100755
--- a/indoteknik_custom/views/sale_order.xml
+++ b/indoteknik_custom/views/sale_order.xml
@@ -72,6 +72,7 @@
<field name="flash_sale"/>
<field name="margin_after_delivery_purchase"/>
<field name="percent_margin_after_delivery_purchase"/>
+ <field name="total_weight"/>
</field>
<field name="analytic_account_id" position="after">
<field name="customer_type" required="1"/>
@@ -80,6 +81,7 @@
<field name="email" required="1"/>
<field name="unreserve_id"/>
<field name="due_id" readonly="1"/>
+ <field name="vendor_approval_id" readonly="1"/>
<field name="source_id" domain="[('id', 'in', [32, 59, 60, 61])]" required="1"/>
<button name="override_allow_create_invoice"
string="Override Create Invoice"
@@ -117,7 +119,7 @@
</xpath>
<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="vendor_md_id" readonly="1" options="{'no_create':True}"/>
+ <field name="vendor_md_id" optional="hide"/>
<field name="purchase_price" attrs="
{
'readonly': [
@@ -127,14 +129,15 @@
]
}
"/>
- <field name="purchase_price_md" readonly="1"/>
+ <field name="purchase_price_md" optional="hide"/>
<field name="purchase_tax_id" attrs="{'readonly': [('parent.approval_status', '!=', False)]}" domain="[('type_tax_use','=','purchase')]" options="{'no_create':True}"/>
<field name="item_percent_margin"/>
<field name="item_margin" optional="hide"/>
+ <field name="margin_md" optional="hide"/>
<field name="note" optional="hide"/>
<field name="note_procurement" optional="hide"/>
<field name="vendor_subtotal" optional="hide"/>
- <field name="weight" optional="hide"/>
+ <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"/>
</xpath>
diff --git a/indoteknik_custom/views/vendor_approval.xml b/indoteknik_custom/views/vendor_approval.xml
index c3f5ee77..605edfbf 100644
--- a/indoteknik_custom/views/vendor_approval.xml
+++ b/indoteknik_custom/views/vendor_approval.xml
@@ -7,8 +7,9 @@
<field name="arch" type="xml">
<tree default_order="create_date desc" create="0">
<field name="number"/>
- <field name="partner_id"/>
+ <field name="create_date_so"/>
<field name="order_id"/>
+ <field name="partner_id"/>
<field name="state"/>
</tree>
</field>
@@ -20,11 +21,17 @@
<field name="arch" type="xml">
<tree>
<field name="product_id"/>
+ <field name="sales_price"/>
<field name="product_uom_qty"/>
+ <field name="sales_tax_id"/>
+ <field name="margin_after"/>
<field name="vendor_id"/>
<field name="vendor_md_id"/>
<field name="purchase_price"/>
<field name="purchase_price_md"/>
+ <field name="margin_before"/>
+ <field name="purchase_tax_id"/>
+ <field name="percent_margin_difference"/>
</tree>
</field>
</record>
@@ -38,12 +45,12 @@
<button name="action_approve"
string="Approve"
type="object"
- attrs="{'invisible': [('state', '=', 'done')]}"
+ attrs="{'invisible': [('state', 'not in', ['draft'])]}"
/>
<button name="action_reject"
- string="Cancel"
+ string="Reject"
type="object"
- attrs="{'invisible': [('state', '=', 'cancel')]}"
+ attrs="{'invisible': [('state', 'not in', ['draft'])]}"
/>
</header>
<sheet>
@@ -52,6 +59,7 @@
<field name="partner_id" readonly="1"/>
<field name="order_id" readonly="1"/>
<field name="state" readonly="1"/>
+ <field name="create_date_so" readonly="1"/>
</group>
</group>
<notebook>