diff options
| author | Azka Nathan <darizkyfaz@gmail.com> | 2024-09-12 10:35:01 +0700 |
|---|---|---|
| committer | Azka Nathan <darizkyfaz@gmail.com> | 2024-09-12 10:35:01 +0700 |
| commit | 16acaa437f203ccfa52aba132225b2bb82ac1c79 (patch) | |
| tree | d4ce062668f1f6d2642e5280f979e60d0acf05a0 /indoteknik_custom/models | |
| parent | f03e6dc2ee2f3cd34eca15e81cd8964c07089ef4 (diff) | |
| parent | a8e539c92236453ce7aad06d23cf117f4b7239fc (diff) | |
Merge branch 'production' into unreserved_permission
# Conflicts:
# indoteknik_api/controllers/api_v1/cart.py
# indoteknik_custom/models/sale_order.py
Diffstat (limited to 'indoteknik_custom/models')
| -rwxr-xr-x | indoteknik_custom/models/__init__.py | 1 | ||||
| -rw-r--r-- | indoteknik_custom/models/commision.py | 1 | ||||
| -rwxr-xr-x | indoteknik_custom/models/product_template.py | 6 | ||||
| -rwxr-xr-x | indoteknik_custom/models/purchase_order.py | 60 | ||||
| -rwxr-xr-x | indoteknik_custom/models/res_users.py | 1 | ||||
| -rwxr-xr-x | indoteknik_custom/models/sale_order.py | 58 | ||||
| -rw-r--r-- | indoteknik_custom/models/solr/__init__.py | 3 | ||||
| -rw-r--r-- | indoteknik_custom/models/solr/website_categories_management.py | 114 | ||||
| -rw-r--r-- | indoteknik_custom/models/website_categories_management.py | 36 | ||||
| -rw-r--r-- | indoteknik_custom/models/website_categories_management_line.py | 22 | ||||
| -rw-r--r-- | indoteknik_custom/models/website_user_cart.py | 3 |
11 files changed, 283 insertions, 22 deletions
diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index fe3e02d4..b225c687 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -39,6 +39,7 @@ from . import website_brand_homepage from . import website_categories_homepage from . import website_categories_lob from . import website_categories_management +from . import website_categories_management_line from . import website_content from . import website_page_content from . import website_user_cart diff --git a/indoteknik_custom/models/commision.py b/indoteknik_custom/models/commision.py index c5809005..48f1c7f6 100644 --- a/indoteknik_custom/models/commision.py +++ b/indoteknik_custom/models/commision.py @@ -261,6 +261,7 @@ class CustomerCommision(models.Model): ('move_id.invoice_date', '>=', self.date_from), ('move_id.invoice_date', '<=', self.date_to), ('product_id.x_manufacture', 'in', brand), + ('exclude_from_invoice_tab', '=', False), ] invoice_lines = self.env['account.move.line'].search(where, order='id') for invoice_line in invoice_lines: diff --git a/indoteknik_custom/models/product_template.py b/indoteknik_custom/models/product_template.py index e6778758..000ee3bf 100755 --- a/indoteknik_custom/models/product_template.py +++ b/indoteknik_custom/models/product_template.py @@ -338,9 +338,9 @@ class ProductTemplate(models.Model): return values def write(self, vals): - for rec in self: - if rec.id == 224484: - raise UserError('Tidak dapat mengubah produk sementara') + # for rec in self: + # if rec.id == 224484: + # raise UserError('Tidak dapat mengubah produk sementara') return super(ProductTemplate, self).write(vals) diff --git a/indoteknik_custom/models/purchase_order.py b/indoteknik_custom/models/purchase_order.py index 8ec904a9..edcbbb19 100755 --- a/indoteknik_custom/models/purchase_order.py +++ b/indoteknik_custom/models/purchase_order.py @@ -31,6 +31,7 @@ class PurchaseOrder(models.Model): ('approved', 'Approved'), ], string='Approval Status', readonly=True, copy=False, index=True, tracking=3) delivery_amount = fields.Float('Delivery Amount', compute='compute_delivery_amount') + delivery_amt = fields.Float('Delivery Amt') total_margin = fields.Float( 'Margin', compute='compute_total_margin', help="Total Margin in Sales Order Header") @@ -66,6 +67,61 @@ class PurchaseOrder(models.Model): ('printed', 'Printed') ], string='Printed?', copy=False, tracking=True) date_done_picking = fields.Datetime(string='Date Done Picking', compute='get_date_done') + bills_dp_id = fields.Many2one('account.move', string='Bills DP') + grand_total = fields.Monetary(string='Grand Total', help='Amount total + amount delivery', compute='_compute_grand_total') + + def _compute_grand_total(self): + for order in self: + if order.delivery_amt: + order.grand_total = order.delivery_amt + order.amount_total + else: + order.grand_total = order.amount_total + + def create_bill_dp(self): + if not self.env.user.is_accounting: + raise UserError('Hanya Accounting yang bisa bikin bill dp') + + current_date = datetime.utcnow() + data_bills = { + 'partner_id': self.partner_id.id, + 'partner_shipping_id': self.partner_id.id, + 'ref': self.name, + 'invoice_date': current_date, + 'date': current_date, + 'move_type': 'in_invoice' + + } + + bills = self.env['account.move'].create([data_bills]) + + product_dp = self.env['product.product'].browse(229625) + + data_line_bills = { + 'move_id': bills.id, + 'product_id': product_dp.id, #product down payment + 'account_id': 401, #Uang Muka persediaan barang dagang + 'quantity': 1, + 'product_uom_id': 1, + 'tax_ids': [line[0].taxes_id.id for line in self.order_line], + } + + + bills_line = self.env['account.move.line'].create([data_line_bills]) + + self.bills_dp_id = bills.id + + move_line = bills.line_ids + move_line.name = '[IT.121456] Down Payment' + move_line.partner_id = self.partner_id.id + + return { + 'name': _('Account Move'), + 'view_mode': 'tree,form', + 'res_model': 'account.move', + 'target': 'current', + 'type': 'ir.actions.act_window', + 'domain': [('id', '=', bills.id)] + } def get_date_done(self): picking = self.env['stock.picking'].search([ @@ -624,6 +680,8 @@ class PurchaseOrder(models.Model): purchase_price = line.price_subtotal if line.order_id.delivery_amount > 0: purchase_price += line.delivery_amt_line + if line.order_id.delivery_amt > 0: + purchase_price += line.order_id.delivery_amt real_item_margin = sales_price - purchase_price sum_margin += real_item_margin @@ -666,6 +724,8 @@ class PurchaseOrder(models.Model): purchase_price = po_line.price_subtotal / po_line.product_qty * line.qty_po if line.purchase_order_id.delivery_amount > 0: purchase_price += (po_line.delivery_amt_line / po_line.product_qty) * line.qty_po + if line.purchase_order_id.delivery_amt > 0: + purchase_price += line.purchase_order_id.delivery_amt real_item_margin = sales_price - purchase_price sum_margin += real_item_margin diff --git a/indoteknik_custom/models/res_users.py b/indoteknik_custom/models/res_users.py index 33f64ce3..70a7dc53 100755 --- a/indoteknik_custom/models/res_users.py +++ b/indoteknik_custom/models/res_users.py @@ -11,6 +11,7 @@ class ResUsers(models.Model): activation_token = fields.Char(string="Activation Token") otp_code = fields.Char(string='OTP Code') otp_create_date = fields.Datetime(string='OTP Create Date') + payment_terms_id = fields.Many2one('account.payment.term', related='partner_id.property_payment_term_id', string='Payment Terms') def _generate_otp(self): for user in self: diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index abfbb799..023cc5e6 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -88,6 +88,8 @@ class SaleOrder(models.Model): voucher_id = fields.Many2one(comodel_name='voucher', string='Voucher', copy=False) applied_voucher_id = fields.Many2one(comodel_name='voucher', string='Applied Voucher', copy=False) amount_voucher_disc = fields.Float(string='Voucher Discount') + applied_voucher_shipping_id = fields.Many2one(comodel_name='voucher', string='Applied Voucher', copy=False) + amount_voucher_shipping_disc = fields.Float(string='Voucher Discount') source_id = fields.Many2one('utm.source', 'Source', domain="[('id', 'in', [32, 59, 60, 61])]", required=True) estimated_arrival_days = fields.Integer('Estimated Arrival Days', default=0) email = fields.Char(string='Email') @@ -110,6 +112,7 @@ class SaleOrder(models.Model): note_website = fields.Char(string="Note Website") use_button = fields.Boolean(string='Using Calculate Selling Price', copy=False) unreserve_id = fields.Many2one('stock.picking', 'Unreserve Picking') + voucher_shipping_id = fields.Many2one(comodel_name='voucher', string='Voucher Shipping', copy=False) def do_unreserve(self): user_id = self.env.user.id @@ -641,6 +644,9 @@ class SaleOrder(models.Model): if not order.client_order_ref and order.create_date > datetime(2024, 6, 27): raise UserError("Customer Reference kosong, di isi dengan NO PO jika PO tidak ada mohon ditulis Tanpa PO") + + if not order.commitment_date and order.create_date > datetime(2024, 9, 12): + raise UserError("Expected Delivery Date kosong, wajib diisi") 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') @@ -754,7 +760,7 @@ class SaleOrder(models.Model): delivery_amt = order.delivery_amt else: delivery_amt = 0 - order.total_percent_margin = round((order.total_margin / (order.amount_untaxed-delivery_amt)) * 100, 2) + order.total_percent_margin = round((order.total_margin / (order.amount_untaxed-delivery_amt-order.fee_third_party)) * 100, 2) # order.total_percent_margin = round((order.total_margin / (order.amount_untaxed)) * 100, 2) @api.onchange('sales_tax_id') @@ -791,6 +797,28 @@ class SaleOrder(models.Model): self.apply_voucher() + def action_apply_voucher_shipping(self): + for line in self.order_line: + if line.order_promotion_id: + raise UserError('Voucher tidak dapat digabung dengan promotion program') + + voucher = self.voucher_shipping_id + if voucher.limit > 0 and voucher.count_order >= voucher.limit: + raise UserError('Voucher tidak dapat digunakan karena sudah habis digunakan') + + partner_voucher_orders = [] + for order in voucher.order_ids: + if order.partner_id.id == self.partner_id.id: + partner_voucher_orders.append(order) + + if voucher.limit_user > 0 and len(partner_voucher_orders) >= voucher.limit_user: + raise UserError('Voucher tidak dapat digunakan karena Customer ini sudah menghabiskan kuota voucher') + + if self.pricelist_id.id in [x.id for x in voucher.excl_pricelist_ids]: + raise UserError('Voucher tidak dapat digunakan karena pricelist ini tidak berlaku pada voucher') + + self.apply_voucher_shipping() + def apply_voucher(self): order_line = [] for line in self.order_line: @@ -832,6 +860,29 @@ class SaleOrder(models.Model): self.amount_voucher_disc = voucher['discount']['all'] self.applied_voucher_id = self.voucher_id + def apply_voucher_shipping(self): + for order in self: + delivery_amt = order.delivery_amt + voucher = order.voucher_shipping_id + + if voucher: + max_discount_amount = voucher.discount_amount + voucher_type = voucher.discount_type + + if voucher_type == 'fixed_price': + discount = max_discount_amount + elif voucher_type == 'percentage': + discount = delivery_amt * (max_discount_amount / 100) + + delivery_amt -= discount + + delivery_amt = max(delivery_amt, 0) + + order.delivery_amt = delivery_amt + + order.amount_voucher_shipping_disc = discount + order.applied_voucher_shipping_id = order.voucher_id.id + def cancel_voucher(self): self.applied_voucher_id = False self.amount_voucher_disc = 0 @@ -840,6 +891,11 @@ class SaleOrder(models.Model): line.discount = line.initial_discount line.initial_discount = False + def cancel_voucher_shipping(self): + self.delivery_amt + self.amount_voucher_shipping_disc + self.applied_voucher_shipping_id = False + self.amount_voucher_shipping_disc = 0 + def action_web_approve(self): if self.env.uid != self.partner_id.user_id.id: raise UserError('You are not authorized to approve this order. Only %s can approve this order.' % self.partner_id.user_id.name) diff --git a/indoteknik_custom/models/solr/__init__.py b/indoteknik_custom/models/solr/__init__.py index 606c0035..dafd5a1e 100644 --- a/indoteknik_custom/models/solr/__init__.py +++ b/indoteknik_custom/models/solr/__init__.py @@ -10,4 +10,5 @@ from . import x_banner_banner from . import product_public_category from . import x_banner_category from . import promotion_program -from . import promotion_program_line
\ No newline at end of file +from . import promotion_program_line +from . import website_categories_management
\ No newline at end of file diff --git a/indoteknik_custom/models/solr/website_categories_management.py b/indoteknik_custom/models/solr/website_categories_management.py new file mode 100644 index 00000000..0a40a356 --- /dev/null +++ b/indoteknik_custom/models/solr/website_categories_management.py @@ -0,0 +1,114 @@ +from odoo import models, fields, api +from datetime import datetime +import json + +class WebsiteCategoriesHomepage(models.Model): + _inherit = 'website.categories.management' + + last_update_solr = fields.Datetime('Last Update Solr') + + def solr(self): + """Returns the Solr connection object.""" + return self.env['apache.solr'].connect('category_management') + + def update_last_update_solr(self): + """Updates the last sync time for the record.""" + self.last_update_solr = datetime.utcnow() + + def _create_solr_queue(self, function_name): + """Creates unique Solr queue for each record.""" + for rec in self: + self.env['apache.solr.queue'].create_unique({ + 'res_model': self._name, + 'res_id': rec.id, + 'function_name': function_name + }) + + @api.constrains('status') + def _create_solr_queue_sync_status(self): + """Triggers Solr sync when the status changes.""" + self._create_solr_queue('_sync_status_category_homepage_solr') + + @api.constrains('category_id', 'category_id2', 'sequence') + def _create_solr_queue_sync_category_homepage(self): + """Triggers Solr sync when categories or sequence change.""" + self._create_solr_queue('_sync_category_management_to_solr') + + def action_sync_to_solr(self): + """Manual action to sync selected categories to Solr.""" + category_ids = self.env.context.get('active_ids', []) + categories = self.search([('id', 'in', category_ids)]) + categories._create_solr_queue('_sync_category_management_to_solr') + + def unlink(self): + """Overrides unlink method to remove records from Solr.""" + for rec in self: + self.solr().delete(rec.id) + self.solr().optimize() + self.solr().commit() + return super(WebsiteCategoriesHomepage, self).unlink() + + def _sync_status_category_homepage_solr(self): + """Syncs status to Solr or deletes if not active.""" + for rec in self: + if rec.status == 'tayang': + rec._sync_category_management_to_solr() + else: + rec.unlink() + + def _sync_category_management_to_solr(self): + """Syncs categories (Level 1, 2, and 3) to Solr.""" + solr_model = self.env['apache.solr'] + + for category in self: + if category.status != 'tayang': + continue + + # Prepare Level 1 document + document = { + 'id': category.id, + 'sequence_i': category.sequence or '', + 'category_id_i': category.category_id.id, + 'name_s': category.category_id.name, + 'numFound_i': len(category.category_id.product_tmpl_ids), + 'image_s': self.env['ir.attachment'].api_image( + 'product.public.category', 'image_1920', category.category_id.id + ), + 'categories': [] + } + + # Prepare Level 2 documents + for category_level_2 in category.line_ids.mapped('category_id2'): + level_2_doc = { + 'id_level_2': category_level_2.id, + 'name': category_level_2.name, + 'numFound': len(category_level_2.product_tmpl_ids), + 'image': self.env['ir.attachment'].api_image( + 'product.public.category', 'image_1920', category_level_2.id + ), + 'child_frontend_id_i': [] + } + + # Prepare Level 3 documents + for category_level_3 in category_level_2.child_frontend_id2: + level_3_doc = { + 'id_level_3': category_level_3.id, + 'name': category_level_3.name, + 'numFound': len(category_level_3.product_tmpl_ids), + 'image': self.env['ir.attachment'].api_image( + 'product.public.category', 'image_1920', category_level_3.id + ), + } + level_2_doc['child_frontend_id_i'].append(json.dumps(level_3_doc)) + + # Add Level 2 document to Level 1 + document['categories'].append(json.dumps(level_2_doc)) + + # Sync document with Solr + self.solr().add([document]) + category.update_last_update_solr() + + # Commit and optimize Solr changes + self.solr().commit() + self.solr().optimize() + diff --git a/indoteknik_custom/models/website_categories_management.py b/indoteknik_custom/models/website_categories_management.py index 208b07a2..e430ef5f 100644 --- a/indoteknik_custom/models/website_categories_management.py +++ b/indoteknik_custom/models/website_categories_management.py @@ -6,8 +6,8 @@ class WebsiteCategoriesManagement(models.Model): _rec_name = 'category_id' category_id = fields.Many2one('product.public.category', string='Category Level 1', help='table ecommerce category', domain=lambda self: self._get_default_category_domain()) - category_id2 = fields.Many2many(comodel_name='product.public.category', relation='website_categories_category_id2_rel',column1='website_categories_homepage_id', column2='product_public_category_id', string='Category Level 2', copy=False) sequence = fields.Integer(string='Sequence') + line_ids = fields.One2many('website.categories.management.line', 'management_id', string='Category Level 2 Lines', auto_join=True) status = fields.Selection([ ('tayang', 'Tayang'), ('tidak_tayang', 'Tidak Tayang') @@ -17,11 +17,11 @@ class WebsiteCategoriesManagement(models.Model): def _onchange_category_id(self): domain = {} if self.category_id != self._origin.category_id: # Check if the category_id has changed - self.category_id2 = [(5, 0, 0)] # Clear the category_id2 field if category_id has changed + self.line_ids = [(5, 0, 0)] # Clear the lines if category_id has changed if self.category_id: - domain['category_id2'] = [('parent_frontend_id', '=', self.category_id.id)] + domain['line_ids'] = [('parent_frontend_id', '=', self.category_id.id)] else: - domain['category_id2'] = [] + domain['line_ids'] = [] return {'domain': domain} @@ -42,24 +42,30 @@ class WebsiteCategoriesManagement(models.Model): def _check_category_consistency(self): for record in self: - category_ids = record.category_id2.ids - for category in record.category_id2: - for child_category in category.child_frontend_id2: - if child_category.parent_frontend_id.id not in category_ids: + category_level2_ids = record.line_ids.mapped('category_id2.id') # Get all Category Level 2 IDs + for line in record.line_ids: + for category_level3 in line.category_id3_ids: # Loop through selected Category Level 3 + if category_level3.parent_frontend_id.id not in category_level2_ids: raise ValidationError( - f"Category Level 3 {child_category.name} bukan bagian dari category Level 2 {category.name}") + f"Category Level 3 '{category_level3.name}' bukan bagian dari Category Level 2 '{line.category_id2.name}'") def unlink(self): - for record in self.category_id2: - if record.id: + for record in self.line_ids: + if record.category_id2: related_categories = self.env['product.public.category'].search([ - ('id', 'in', record.ids) + ('id', '=', record.category_id2.id) ]) for category in related_categories: - for category3 in record.child_frontend_id2.ids: - if category3 in category.child_frontend_id2.ids: + # Iterate through the Category Level 3 related to the current Category Level 2 + for category3 in record.category_id3_ids: + # If Category Level 3 is linked to Category Level 2, remove the link + if category3.id in category.child_frontend_id2.ids: category.write({ - 'child_frontend_id2': [(3, category3)] + 'child_frontend_id2': [(3, category3.id)] + # Remove the link between Category Level 2 and Category Level 3 }) + return super(WebsiteCategoriesManagement, self).unlink() + + diff --git a/indoteknik_custom/models/website_categories_management_line.py b/indoteknik_custom/models/website_categories_management_line.py new file mode 100644 index 00000000..2f97ddfa --- /dev/null +++ b/indoteknik_custom/models/website_categories_management_line.py @@ -0,0 +1,22 @@ +from odoo import fields, models, api +from odoo.exceptions import ValidationError + +class WebsiteCategoriesManagementLine(models.Model): + _name = 'website.categories.management.line' + _order = 'sequence' + + sequence = fields.Integer(string='Sequence') + management_id = fields.Many2one('website.categories.management', string='Management Reference', required=True, ondelete='cascade') + category_id2 = fields.Many2one('product.public.category', string='Category Level 2', required=True,) + category_id3_ids = fields.Many2many('product.public.category', string='Category Level 3') + + @api.onchange('category_id2') + def _onchange_category_id2(self): + """ Update domain for category_id3_ids based on category_id2 """ + if self.category_id2: + domain_category_id3_ids = [('parent_frontend_id', '=', self.category_id2.id)] + else: + domain_category_id3_ids = [] + + return {'domain': {'category_id3_ids': domain_category_id3_ids}} + diff --git a/indoteknik_custom/models/website_user_cart.py b/indoteknik_custom/models/website_user_cart.py index 0af22d47..b0cf47f7 100644 --- a/indoteknik_custom/models/website_user_cart.py +++ b/indoteknik_custom/models/website_user_cart.py @@ -130,8 +130,7 @@ class WebsiteUserCart(models.Model): if voucher_shipping: voucher_shipping_info = voucher_shipping.apply(order_line) - discount_voucher_shipping = voucher_shipping_info['discount']['all'] - subtotal -= discount_voucher_shipping + discount_voucher_shipping = voucher_shipping_info['discount']['all'] tax = round(subtotal * 0.11) grand_total = subtotal + tax |
