diff options
| author | Azka Nathan <darizkyfaz@gmail.com> | 2024-08-14 13:37:16 +0700 |
|---|---|---|
| committer | Azka Nathan <darizkyfaz@gmail.com> | 2024-08-14 13:37:16 +0700 |
| commit | 72befb1e3401a4c31dbf2698963ec52c5baba8cd (patch) | |
| tree | 314c9219b47c02464fb2b62922a7b3150d308132 | |
| parent | 3c179deae0dbf618f6171003532dc86c48ada367 (diff) | |
| parent | ed089761d43b20ecc4190ca9d88a0bdb769d81f2 (diff) | |
Merge branch 'production' of bitbucket.org:altafixco/indoteknik-addons into production
| -rwxr-xr-x | indoteknik_custom/models/sale_order.py | 96 | ||||
| -rw-r--r-- | indoteknik_custom/models/sale_order_line.py | 146 | ||||
| -rw-r--r-- | indoteknik_custom/views/airway_bill.xml | 2 | ||||
| -rw-r--r-- | indoteknik_custom/views/product_sla.xml | 2 | ||||
| -rwxr-xr-x | indoteknik_custom/views/sale_order.xml | 6 |
5 files changed, 220 insertions, 32 deletions
diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 14957b24..0b0a679f 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -108,6 +108,7 @@ class SaleOrder(models.Model): date_driver_arrival = fields.Datetime(string='Arrival Date', compute='_compute_date_kirim', copy=False) date_driver_departure = fields.Datetime(string='Departure Date', compute='_compute_date_kirim', copy=False) note_website = fields.Char(string="Note Website") + use_button = fields.Boolean(string='Using Calculate Selling Price', copy=False) def _compute_date_kirim(self): for rec in self: @@ -842,5 +843,98 @@ class SaleOrder(models.Model): } } + def calculate_selling_price(self): + # ongkos kirim, biaya pihak ketiga calculate @stephan + # TODO voucher @stephan + # vendor hilangin child di field SO Line @stephan + # button pindahin @stephan + # last so 1 tahun ke belakang @stephan + # pastikan harga beli 1 tahun ke belakang jg + # harga yg didapat dari semua kumpulan parent parner dan child nya + # counter di klik berapa banyak @stephan + for order_line in self.order_line: + if not order_line.product_id: + continue + current_time = datetime.now() + delta_time = current_time - timedelta(days=365) + delta_time = delta_time.strftime('%Y-%m-%d %H:%M:%S') + + # Initialize partners list with parent_id or partner_id + partners = [] + parent_id = self.partner_id.parent_id or self.partner_id + + # Add all child_ids and the parent itself to partners as IDs + partners.extend(parent_id.child_ids.ids) + partners.append(parent_id.id) + + rec_purchase_price, rec_taxes_id, rec_vendor_id = order_line._get_purchase_price(order_line.product_id) + state = ['sale', 'done'] + last_so = self.env['sale.order.line'].search([ + # ('order_id.partner_id.id', '=', order_line.order_id.partner_id.id), + ('order_id.partner_id', 'in', partners), + ('product_id.id', '=', order_line.product_id.id), + ('order_id.state', 'in', state), + ('id', '!=', order_line.id), + ('order_id.date_order', '>=', delta_time) + ], limit=1, order='create_date desc') + + if rec_vendor_id != last_so.vendor_id.id: + last_so = self.env['sale.order.line'].search([ + # ('order_id.partner_id.id', '=', order_line.order_id.partner_id.id), + ('order_id.partner_id', 'in', partners), + ('product_id.id', '=', order_line.product_id.id), + ('order_id.state', 'in', state), + ('vendor_id', '=', rec_vendor_id), + ('id', '!=', order_line.id), + ('order_id.date_order', '>=', delta_time) + ], limit=1, order='create_date desc') + + if rec_purchase_price != last_so.purchase_price: + rec_taxes = self.env['account.tax'].search([('id', '=', rec_taxes_id)], limit=1) + if rec_taxes.price_include: + selling_price = (rec_purchase_price / 1.11) / (1 - (last_so.item_percent_margin_without_deduction / 100)) + else: + selling_price = rec_purchase_price / (1 - (last_so.item_percent_margin_without_deduction / 100)) + tax_id = last_so.tax_id + for tax in tax_id: + if tax.price_include: + selling_price = selling_price + (selling_price*11/100) + else: + selling_price = selling_price + discount = 0 + elif last_so: + selling_price = last_so.price_unit + tax_id = last_so.tax_id + discount = last_so.discount + else: + selling_price = order_line.price_unit + tax_id = order_line.tax_id + discount = order_line.discount + + elif rec_vendor_id == order_line.vendor_id.id and rec_purchase_price != last_so.purchase_price: + rec_taxes = self.env['account.tax'].search([('id', '=', rec_taxes_id)], limit=1) + if rec_taxes.price_include: + selling_price = (rec_purchase_price / 1.11) / (1 - (last_so.item_percent_margin_without_deduction / 100)) + else: + selling_price = rec_purchase_price / (1 - (last_so.item_percent_margin_without_deduction / 100)) + tax_id = last_so.tax_id + for tax in tax_id: + if tax.price_include: + selling_price = selling_price + (selling_price*11/100) + else: + selling_price = selling_price + discount = 0 + + elif last_so: + selling_price = last_so.price_unit + tax_id = last_so.tax_id + discount = last_so.discount - + else: + selling_price = order_line.price_unit + tax_id = order_line.tax_id + discount = order_line.discount + order_line.price_unit = selling_price + order_line.tax_id = tax_id + order_line.discount = discount + order_line.order_id.use_button = True diff --git a/indoteknik_custom/models/sale_order_line.py b/indoteknik_custom/models/sale_order_line.py index 1f90b821..a64a744c 100644 --- a/indoteknik_custom/models/sale_order_line.py +++ b/indoteknik_custom/models/sale_order_line.py @@ -1,6 +1,6 @@ from odoo import fields, models, api, _ from odoo.exceptions import UserError -from datetime import datetime +from datetime import datetime, timedelta class SaleOrderLine(models.Model): @@ -30,6 +30,7 @@ class SaleOrderLine(models.Model): amount_voucher_disc = fields.Float(string='Voucher Discount') qty_reserved = fields.Float(string='Qty Reserved', compute='_compute_qty_reserved') reserved_from = fields.Char(string='Reserved From', copy=False) + item_percent_margin_without_deduction = fields.Float('%Margin', compute='_compute_item_margin_without_deduction') @api.constrains('note_procurement') def note_procurement_to_apo(self): @@ -40,8 +41,6 @@ class SaleOrderLine(models.Model): for match_so in matches_so: match_so.note_procurement = line.note_procurement - - @api.onchange('product_uom', 'product_uom_qty') def product_uom_change(self): @@ -63,9 +62,9 @@ class SaleOrderLine(models.Model): line.qty_reserved = reserved_qty def _compute_reserved_from(self): - for line in self: - report_stock_forecasted = self.env['report.stock.report_product_product_replenishment'] - report_stock_forecasted._get_report_data(False, [line.product_id.id]) + for line in self: + report_stock_forecasted = self.env['report.stock.report_product_product_replenishment'] + report_stock_forecasted._get_report_data(False, [line.product_id.id]) def _compute_vendor_subtotal(self): for line in self: @@ -74,6 +73,28 @@ class SaleOrderLine(models.Model): else: line.vendor_subtotal = 0 + def _compute_item_margin_without_deduction(self): + for line in self: + if not line.product_id or line.product_id.type == 'service' \ + or line.price_unit <= 0 or line.product_uom_qty <= 0 \ + or not line.vendor_id: + line.item_percent_margin_without_deduction = 0 + continue + # calculate margin without tax + sales_price = line.price_reduce_taxexcl * line.product_uom_qty + + purchase_price = line.purchase_price + if line.purchase_tax_id.price_include: + purchase_price = line.purchase_price / 1.11 + + purchase_price = purchase_price * line.product_uom_qty + margin_per_item = sales_price - purchase_price + + if sales_price > 0: + line.item_percent_margin_without_deduction = round((margin_per_item / sales_price), 2) * 100 + else: + line.item_percent_margin_without_deduction = 0 + def compute_item_margin(self): for line in self: if not line.product_id or line.product_id.type == 'service' \ @@ -105,59 +126,128 @@ class SaleOrderLine(models.Model): @api.onchange('vendor_id') def onchange_vendor_id(self): + # TODO : need to change this logic @stephan if not self.product_id or self.product_id.type == 'service': return elif self.product_id.categ_id.id == 34: # finish good / manufacturing only cost = self.product_id.standard_price self.purchase_price = 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), - ('product_id', '=', self.product_id.id)], - limit=1, order='count_trx_po desc, count_trx_po_vendor desc') - price, taxes = self._get_valid_purchase_price(purchase_price) - self.purchase_price = price - self.purchase_tax_id = taxes - else: - purchase_price = self.env['purchase.pricelist'].search( - [('vendor_id', '=', self.vendor_id.id), ('product_id', '=', self.product_id.id)], - limit=1, order='count_trx_po desc, count_trx_po_vendor desc') - price, taxes = self._get_valid_purchase_price(purchase_price) + # purchase_price = self.env['purchase.pricelist'].search( + # [('vendor_id', '=', self.product_id.x_manufacture.override_vendor_id.id), + # ('product_id', '=', self.product_id.id)], + # 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_tax_id = taxes + # else: + # purchase_price = self.env['purchase.pricelist'].search( + # [('vendor_id', '=', self.vendor_id.id), ('product_id', '=', self.product_id.id)], + # limit=1, order='count_trx_po desc, count_trx_po_vendor desc') + # price, taxes = self._get_valid_purchase_price(purchase_price) + # self.purchase_price = price + # self.purchase_tax_id = taxes + + # def _calculate_selling_price(self): + # rec_purchase_price, rec_taxes, rec_vendor_id = self._get_purchase_price(self.product_id) + # state = ['sale', 'done'] + # last_so = self.env['sale.order.line'].search([ + # ('order_id.partner_id.id', '=', self.order_id.partner_id.id), + # ('product_id.id', '=', self.product_id.id), + # ('order_id.state', 'in', state) + # ], limit=1, order='create_date desc') + # # if rec_vendor_id == self.vendor_id and rec_purchase_price == last_so.purchase_price: + # # selling_price = last_so.price_unit + # # tax_id = last_so.tax_id + # if rec_vendor_id == self.vendor_id and rec_purchase_price != last_so.purchase_price: + # if rec_taxes.price_include: + # selling_price = (rec_purchase_price/1.11) / (1-(last_so.line_item_margin / 100)) + # else: + # selling_price = rec_purchase_price / (1-(last_so.line_item_margin / 100)) + # tax_id = last_so.tax_id + # elif rec_vendor_id != last_so.vendor_id: + # last_so = self.env['sale.order.line'].search([ + # ('order_id.partner_id.id', '=', self.order_id.partner_id.id), + # ('product_id.id', '=', self.product_id.id), + # ('state', 'in', state), + # ('vendor_id', '=', rec_vendor_id) + # ], limit=1, order='order_id.date_order desc') + # selling_price = last_so.price_unit + # tax_id = last_so.tax_id + # else: + # selling_price = last_so.price_unit + # tax_id = last_so.tax_id + # self.price_unit = selling_price + # self.tax_id = tax_id + + def _get_purchase_price(self, product_id): + purchase_price = self.env['purchase.pricelist'].search( + [('product_id', '=', product_id.id), + ('is_winner', '=', True)], + limit=1) + + return self._get_valid_purchase_price(purchase_price) + + def _get_purchase_price_by_vendor(self, product_id, vendor_id): + purchase_price = self.env['purchase.pricelist'].search( + [('product_id', '=', product_id.id), + ('vendor_id', '=', vendor_id.id), + # ('is_winner', '=', True) + ], + limit=1) + + return self._get_valid_purchase_price(purchase_price) def _get_valid_purchase_price(self, purchase_price): + current_time = datetime.now() + delta_time = current_time - timedelta(days=365) + # delta_time = delta_time.strftime('%Y-%m-%d %H:%M:%S') + price = 0 taxes = '' + vendor_id = '' human_last_update = purchase_price.human_last_update or datetime.min system_last_update = purchase_price.system_last_update or datetime.min - if purchase_price.taxes_product_id.type_tax_use == 'purchase': + if purchase_price.taxes_product_id.type_tax_use == 'purchase': price = purchase_price.product_price taxes = purchase_price.taxes_product_id.id + vendor_id = purchase_price.vendor_id.id + if delta_time > human_last_update: + price = 0 + taxes = '' + vendor_id = '' if system_last_update > human_last_update: if purchase_price.taxes_system_id.type_tax_use == 'purchase': price = purchase_price.system_price taxes = purchase_price.taxes_system_id.id + vendor_id = purchase_price.vendor_id.id + if delta_time > system_last_update: + price = 0 + taxes = '' + vendor_id = '' - return price, taxes + return price, taxes, vendor_id @api.onchange('product_id') def product_id_change(self): + # need to change purchase price logic @stephan super(SaleOrderLine, self).product_id_change() for line in self: if line.product_id and line.product_id.type == 'product': - query = [('product_id', '=', line.product_id.id)] - if line.product_id.x_manufacture.override_vendor_id: - query = [('product_id', '=', line.product_id.id), - ('vendor_id', '=', line.product_id.x_manufacture.override_vendor_id.id)] - purchase_price = self.env['purchase.pricelist'].search( - query, limit=1, order='count_trx_po desc, count_trx_po_vendor desc') - line.vendor_id = purchase_price.vendor_id + # query = [('product_id', '=', line.product_id.id)] + # if line.product_id.x_manufacture.override_vendor_id: + # query = [('product_id', '=', line.product_id.id), + # ('vendor_id', '=', line.product_id.x_manufacture.override_vendor_id.id)] + # purchase_price = self.env['purchase.pricelist'].search( + # query, limit=1, order='count_trx_po desc, count_trx_po_vendor desc') + price, taxes, vendor_id = self._get_purchase_price(line.product_id) + line.vendor_id = vendor_id line.tax_id = line.order_id.sales_tax_id - price, taxes = line._get_valid_purchase_price(purchase_price) + # price, taxes = line._get_valid_purchase_price(purchase_price) line.purchase_price = price + line.purchase_tax_id = taxes attribute_values = line.product_id.product_template_attribute_value_ids.mapped('name') attribute_values_str = ', '.join(attribute_values) if attribute_values else '' diff --git a/indoteknik_custom/views/airway_bill.xml b/indoteknik_custom/views/airway_bill.xml index 015f20f2..626a6763 100644 --- a/indoteknik_custom/views/airway_bill.xml +++ b/indoteknik_custom/views/airway_bill.xml @@ -94,7 +94,7 @@ <field name="code">model._fetch()</field> <field name="state">code</field> <field name="priority">75</field> - <field name="active">True</field> + <field name="active">False</field> </record> <menuitem id="menu_airway_bill" diff --git a/indoteknik_custom/views/product_sla.xml b/indoteknik_custom/views/product_sla.xml index d0d3f84a..8b0e874b 100644 --- a/indoteknik_custom/views/product_sla.xml +++ b/indoteknik_custom/views/product_sla.xml @@ -48,7 +48,7 @@ <field name="code">model.generate_product_variant_id_sla(limit=150)</field> <field name="state">code</field> <field name="priority">100</field> - <field name="active">True</field> + <field name="active">False</field> </record> <menuitem id="menu_product_sla" diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 04f21d83..1257ff85 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -43,6 +43,10 @@ attrs="{'invisible': ['|', ('applied_voucher_id', '=', False), ('state', 'not in', ['draft','sent'])]}" /> </div> + <button name="calculate_selling_price" + string="Calculate Selling Price" + type="object" + /> </field> <field name="source_id" position="attributes"> <attribute name="invisible">1</attribute> @@ -96,7 +100,7 @@ </attribute> </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')]}"/> + <field name="vendor_id" attrs="{'readonly': [('parent.approval_status', '=', 'approved')]}" domain="[('parent_id', '=', False)]"/> <field name="purchase_price" attrs=" { 'readonly': [ |
