diff options
| author | Rafi Zadanly <zadanlyr@gmail.com> | 2023-07-13 11:31:29 +0700 |
|---|---|---|
| committer | Rafi Zadanly <zadanlyr@gmail.com> | 2023-07-13 11:31:29 +0700 |
| commit | b496b7907c60d8b262ddba42e55dd8485f718fce (patch) | |
| tree | e0c9fd67a600224f0d4279a1b8d3d20de2ec6254 /indoteknik_custom | |
| parent | 5aa6e8f5ed1bd628a5f4559a3f752b6e83ee2c49 (diff) | |
| parent | 5d101afe46c1c1bce87ec2f7e8f18d040bbbc7d3 (diff) | |
Merge branch 'feature/voucher' into development
Diffstat (limited to 'indoteknik_custom')
| -rwxr-xr-x | indoteknik_custom/__manifest__.py | 1 | ||||
| -rwxr-xr-x | indoteknik_custom/models/__init__.py | 1 | ||||
| -rwxr-xr-x | indoteknik_custom/models/sale_order.py | 1 | ||||
| -rw-r--r-- | indoteknik_custom/models/voucher.py | 108 | ||||
| -rwxr-xr-x | indoteknik_custom/security/ir.model.access.csv | 3 | ||||
| -rwxr-xr-x | indoteknik_custom/views/sale_order.xml | 1 | ||||
| -rwxr-xr-x | indoteknik_custom/views/voucher.xml | 86 |
7 files changed, 200 insertions, 1 deletions
diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index 11921285..4fa736f6 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -78,6 +78,7 @@ 'views/requisition.xml', 'views/landedcost.xml', 'views/product_sla.xml', + 'views/voucher.xml', 'report/report.xml', 'report/report_banner_banner.xml', 'report/report_banner_banner2.xml', diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index 4af46dae..9e4d2cf9 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -66,3 +66,4 @@ from . import requisition from . import token_storage from . import product_sla from . import account_move_due_extension +from . import voucher
\ No newline at end of file diff --git a/indoteknik_custom/models/sale_order.py b/indoteknik_custom/models/sale_order.py index 5a3cada9..e54b9ae2 100755 --- a/indoteknik_custom/models/sale_order.py +++ b/indoteknik_custom/models/sale_order.py @@ -86,6 +86,7 @@ class SaleOrder(models.Model): sppkp = fields.Char(string="SPPKP") npwp = fields.Char(string="NPWP") purchase_total = fields.Monetary(string='Purchase Total', compute='_compute_purchase_total') + voucher_id = fields.Many2one(comodel_name='voucher', string='Voucher') def _compute_purchase_total(self): for order in self: diff --git a/indoteknik_custom/models/voucher.py b/indoteknik_custom/models/voucher.py new file mode 100644 index 00000000..b327df6d --- /dev/null +++ b/indoteknik_custom/models/voucher.py @@ -0,0 +1,108 @@ +from odoo import models, fields +from datetime import datetime, timedelta + + +class Voucher(models.Model): + _name = 'voucher' + _rec_name = 'display_name' + + display_name = fields.Char(string='Display Name', compute='_compute_display_name') + name = fields.Char(string='Name') + image = fields.Binary(string='Image') + code = fields.Char(string='Code', help='Kode voucher yang akan berlaku untuk pengguna') + description = fields.Text(string='Description') + discount_amount = fields.Integer(string='Discount Amount') + discount_type = fields.Selection( + selection=[ + ('percentage', 'Percentage'), + ('fixed_price', 'Fixed Price'), + ], + string='Discount Type', + help='Select the type of discount:\n' + '- Percentage: Persentage dari total harga.\n' + '- Fixed Price: Jumlah tetap yang dikurangi dari harga total.' + ) + visibility = fields.Selection( + selection=[ + ('public', 'Public'), + ('private', 'Private') + ], + string='Visibility', + help='Select the visibility:\n' + '- Public: Ditampilkan kepada seluruh pengguna.\n' + '- Private: Tidak ditampilkan kepada seluruh pengguna.' + ) + start_time = fields.Datetime(string='Start Time') + end_time = fields.Datetime(string='End Time') + min_purchase_amount = fields.Integer(string='Min. Purchase Amount', help='Nominal minimum untuk dapat menggunakan voucher. Isi 0 jika tidak ada minimum purchase amount') + max_discount_amount = fields.Integer(string='Max. Discount Amount', help='Max nominal terhadap persentase diskon') + order_ids = fields.One2many('sale.order', 'voucher_id', string='Order') + + def _compute_display_name(self): + for voucher in self: + voucher.display_name = f'{voucher.name} ({voucher.code})' + + def res_format(self): + datas = [voucher.format() for voucher in self] + return datas + + def format(self): + ir_attachment = self.env['ir.attachment'] + discount_type = self.discount_type + max_discount_amount = self.max_discount_amount if discount_type == 'percentage' else 0 + data = { + 'id': self.id, + 'image': ir_attachment.api_image('voucher', 'image', self.id), + 'name': self.name, + 'code': self.code, + 'description': self.description, + 'discount_amount': self.discount_amount, + 'discount_type': discount_type, + 'remaining_time': self._res_remaining_time(), + 'min_purchase_amount': self.min_purchase_amount, + 'max_discount_amount': max_discount_amount, + } + return data + + def _res_remaining_time(self): + seconds = self._get_remaining_time() + remaining_time = timedelta(seconds=seconds) + hours = remaining_time.seconds // 3600 + minutes = remaining_time.seconds // 60 + if remaining_time.days > 0: + time = remaining_time.days + unit = 'hari' + elif hours > 0: + time = hours + unit = 'jam' + else: + time = minutes + unit = 'menit' + return f'{time} {unit}' + + def _get_remaining_time(self): + calculate_time = self.end_time - datetime.now() + return round(calculate_time.total_seconds()) + + def calculate_discount(self, price): + if price < self.min_purchase_amount: + return 0 + + if self.discount_type == 'fixed_price': + return self.discount_amount + + if self.discount_type == 'percentage': + discount = price * self.discount_amount / 100 + max_disc = self.max_discount_amount + return max_disc if discount > max_disc else discount + + return 0 + + def get_active_voucher(self, parameter): + current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + parameter += [ + ('start_time', '<=', current_time), + ('end_time', '>=', current_time), + ] + vouchers = self.search(parameter, order='min_purchase_amount ASC') + return vouchers
\ No newline at end of file diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index a470fa8f..2b269417 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -55,4 +55,5 @@ access_requisition,access.requisition,model_requisition,,1,1,1,1 access_requisition_line,access.requisition.line,model_requisition_line,,1,1,1,1 access_requisition_purchase_match,access.requisition.purchase.match,model_requisition_purchase_match,,1,1,1,1 access_token_storage,access.token_storage,model_token_storage,,1,1,1,1 -access_product_sla,access.product_sla,model_product_sla,,1,1,1,1
\ No newline at end of file +access_product_sla,access.product_sla,model_product_sla,,1,1,1,1 +access_voucher,access.voucher,model_voucher,,1,1,1,1 diff --git a/indoteknik_custom/views/sale_order.xml b/indoteknik_custom/views/sale_order.xml index 70e3392f..b55fefff 100755 --- a/indoteknik_custom/views/sale_order.xml +++ b/indoteknik_custom/views/sale_order.xml @@ -26,6 +26,7 @@ <field name="delivery_amt"/> <field name="fee_third_party"/> <field name="total_percent_margin"/> + <field name="voucher_id" /> </field> <field name="analytic_account_id" position="after"> <field name="customer_type" attrs="{'required': ['|', ('create_date', '>', '2023-06-28'), ('create_date', '=', False)]}"/> diff --git a/indoteknik_custom/views/voucher.xml b/indoteknik_custom/views/voucher.xml new file mode 100755 index 00000000..cd42586e --- /dev/null +++ b/indoteknik_custom/views/voucher.xml @@ -0,0 +1,86 @@ +<odoo> + <data> + <record id="voucher_action" model="ir.actions.act_window"> + <field name="name">Voucher</field> + <field name="res_model">voucher</field> + <field name="view_mode">tree,form</field> + </record> + + <record id="voucher_tree" model="ir.ui.view"> + <field name="name">Voucher</field> + <field name="model">voucher</field> + <field name="arch" type="xml"> + <tree> + <field name="name"/> + <field name="code"/> + <field name="description"/> + </tree> + </field> + </record> + + <record id="voucher_form" model="ir.ui.view"> + <field name="name">Voucher</field> + <field name="model">voucher</field> + <field name="arch" type="xml"> + <form> + <sheet> + <group> + <group> + <field name="image" widget="image" width="120"/> + <field name="name" required="1" /> + <field name="description" placeholder="Insert short description..." /> + </group> + <group string="Rules"> + <field name="code" required="1" /> + <field name="visibility" required="1" /> + <field name="start_time" required="1"/> + <field name="end_time" required="1"/> + </group> + <group></group> + <group string="Discount Settings"> + <field name="min_purchase_amount" widget="monetary" required="1" /> + <field name="discount_type" required="1" /> + + <label for="max_discount_amount" string="Discount Amount" /> + <div class="d-flex align-items-center"> + <span + class="mr-1 font-weight-bold" + attrs="{'invisible': [('discount_type', '!=', 'fixed_price')]}" + > + Rp + </span> + <field class="mb-0" name="discount_amount" required="1" /> + <span + class="ml-1 font-weight-bold" + attrs="{'invisible': [('discount_type', '!=', 'percentage')]}" + > + % + </span> + </div> + + <field name="max_discount_amount" widget="monetary" required="1" attrs="{'invisible': [('discount_type', '!=', 'percentage')]}"/> + </group> + </group> + <notebook> + <page name="order_page" string="Orders"> + <field name="order_ids" readonly="1"> + <tree> + <field name="name" /> + <field name="amount_total" /> + </tree> + </field> + </page> + </notebook> + </sheet> + </form> + </field> + </record> + + <menuitem id="voucher" + name="Voucher" + parent="website_sale.menu_catalog" + sequence="1" + action="voucher_action" + /> + </data> +</odoo>
\ No newline at end of file |
