summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2023-07-13 11:31:29 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2023-07-13 11:31:29 +0700
commitb496b7907c60d8b262ddba42e55dd8485f718fce (patch)
treee0c9fd67a600224f0d4279a1b8d3d20de2ec6254
parent5aa6e8f5ed1bd628a5f4559a3f752b6e83ee2c49 (diff)
parent5d101afe46c1c1bce87ec2f7e8f18d040bbbc7d3 (diff)
Merge branch 'feature/voucher' into development
-rw-r--r--indoteknik_api/controllers/api_v1/__init__.py1
-rw-r--r--indoteknik_api/controllers/api_v1/sale_order.py137
-rw-r--r--indoteknik_api/controllers/api_v1/voucher.py22
-rwxr-xr-xindoteknik_custom/__manifest__.py1
-rwxr-xr-xindoteknik_custom/models/__init__.py1
-rwxr-xr-xindoteknik_custom/models/sale_order.py1
-rw-r--r--indoteknik_custom/models/voucher.py108
-rwxr-xr-xindoteknik_custom/security/ir.model.access.csv3
-rwxr-xr-xindoteknik_custom/views/sale_order.xml1
-rwxr-xr-xindoteknik_custom/views/voucher.xml86
10 files changed, 314 insertions, 47 deletions
diff --git a/indoteknik_api/controllers/api_v1/__init__.py b/indoteknik_api/controllers/api_v1/__init__.py
index 2afefb34..65bcf926 100644
--- a/indoteknik_api/controllers/api_v1/__init__.py
+++ b/indoteknik_api/controllers/api_v1/__init__.py
@@ -25,3 +25,4 @@ from . import content
from . import midtrans
from . import wati
from . import courier
+from . import voucher \ No newline at end of file
diff --git a/indoteknik_api/controllers/api_v1/sale_order.py b/indoteknik_api/controllers/api_v1/sale_order.py
index aa211b75..e036751e 100644
--- a/indoteknik_api/controllers/api_v1/sale_order.py
+++ b/indoteknik_api/controllers/api_v1/sale_order.py
@@ -58,25 +58,28 @@ class SaleOrder(controller.Controller):
limit = params['value']['limit']
offset = params['value']['offset']
if not params['valid']:
- return self.response(code=400, description=params)
+ return self.response(code=400, description=params)
- partner_child_ids = self.get_partner_child_ids(params['value']['partner_id'])
+ partner_child_ids = self.get_partner_child_ids(
+ params['value']['partner_id'])
domain = [('partner_id', 'in', partner_child_ids)]
context = params['value']['context']
if context == 'quotation':
- domain += ["|","|",("state","=","draft"),("state","=","sent"),("state","=","cancel")]
+ domain += ["|", "|", ("state", "=", "draft"),
+ ("state", "=", "sent"), ("state", "=", "cancel")]
if not context:
- domain += ["|",("state","=","sale"),("state","=","done")]
+ domain += ["|", ("state", "=", "sale"), ("state", "=", "done")]
if params['value']['name']:
name = params['value']['name'].replace(' ', '%')
domain += [
'|',
- ('name', 'ilike', '%'+ name +'%'),
- ('partner_purchase_order_name', 'ilike', '%'+ name +'%')
+ ('name', 'ilike', '%' + name + '%'),
+ ('partner_purchase_order_name', 'ilike', '%' + name + '%')
]
- sale_orders = request.env['sale.order'].search(domain, offset=offset, limit=limit)
+ sale_orders = request.env['sale.order'].search(
+ domain, offset=offset, limit=limit)
data = {
'sale_order_total': request.env['sale.order'].search_count(domain),
'sale_orders': [request.env['sale.order'].api_v1_single_response(x) for x in sale_orders]
@@ -91,9 +94,10 @@ class SaleOrder(controller.Controller):
'id': ['number']
})
if not params['valid']:
- return self.response(code=400, description=params)
-
- partner_child_ids = self.get_partner_child_ids(params['value']['partner_id'])
+ return self.response(code=400, description=params)
+
+ partner_child_ids = self.get_partner_child_ids(
+ params['value']['partner_id'])
domain = [
('id', '=', params['value']['id']),
('partner_id', 'in', partner_child_ids)
@@ -101,8 +105,9 @@ class SaleOrder(controller.Controller):
data = {}
sale_order = request.env['sale.order'].search(domain)
if sale_order:
- data = request.env['sale.order'].api_v1_single_response(sale_order, context='with_detail')
-
+ data = request.env['sale.order'].api_v1_single_response(
+ sale_order, context='with_detail')
+
return self.response(data)
@http.route(PREFIX_PARTNER + 'sale_order/<id>/checkout', auth='public', method=['POST', 'OPTIONS'], csrf=False)
@@ -113,9 +118,10 @@ class SaleOrder(controller.Controller):
'id': ['number']
})
if not params['valid']:
- return self.response(code=400, description=params)
+ return self.response(code=400, description=params)
- partner_child_ids = self.get_partner_child_ids(params['value']['partner_id'])
+ partner_child_ids = self.get_partner_child_ids(
+ params['value']['partner_id'])
domain = [
('id', '=', params['value']['id']),
('partner_id', 'in', partner_child_ids)
@@ -124,13 +130,14 @@ class SaleOrder(controller.Controller):
sale_order = request.env['sale.order'].search(domain)
if sale_order:
sale_order.approval_status = 'pengajuan1'
- data = request.env['sale.order'].api_v1_single_response(sale_order, context='with_detail')
+ data = request.env['sale.order'].api_v1_single_response(
+ sale_order, context='with_detail')
return self.response(data)
@http.route(PREFIX_PARTNER + 'sale_order/<id>/upload_po', auth='public', method=['POST', 'OPTIONS'], csrf=False)
def partner_upload_po_sale_order(self, **kw):
- user_token = self.authenticate()
+ user_token = self.authenticate()
if not user_token:
return self.unauthorized_response()
@@ -144,7 +151,8 @@ class SaleOrder(controller.Controller):
return self.unauthorized_response()
if not params['valid']:
return self.response(code=400, description=params)
- partner_child_ids = self.get_partner_child_ids(params['value']['partner_id'])
+ partner_child_ids = self.get_partner_child_ids(
+ params['value']['partner_id'])
domain = [
('id', '=', params['value']['id']),
('partner_id', 'in', partner_child_ids)
@@ -166,9 +174,11 @@ class SaleOrder(controller.Controller):
md5_valid = rest_api.md5_salt_valid(id, 'sale.order', token)
if not md5_valid:
return self.response('Unauthorized')
-
- sale_order = request.env['sale.order'].sudo().search_read([('id', '=', id)], ['partner_purchase_order_name'])
- attachment = rest_api.get_single_attachment('sale.order', 'partner_purchase_order_file', id)
+
+ sale_order = request.env['sale.order'].sudo().search_read(
+ [('id', '=', id)], ['partner_purchase_order_name'])
+ attachment = rest_api.get_single_attachment(
+ 'sale.order', 'partner_purchase_order_file', id)
if attachment and len(sale_order) > 0:
return rest_api.response_attachment({
'content': attachment['datas'],
@@ -186,9 +196,11 @@ class SaleOrder(controller.Controller):
md5_valid = rest_api.md5_salt_valid(id, 'sale.order', token)
if not md5_valid:
return self.response('Unauthorized')
-
- sale_order = request.env['sale.order'].sudo().search_read([('id', '=', id)], ['name'])
- pdf, type = request.env['ir.actions.report'].sudo().search([('report_name', '=', 'indoteknik_custom.report_saleorder_website')])._render_qweb_pdf([id])
+
+ sale_order = request.env['sale.order'].sudo(
+ ).search_read([('id', '=', id)], ['name'])
+ pdf, type = request.env['ir.actions.report'].sudo().search(
+ [('report_name', '=', 'indoteknik_custom.report_saleorder_website')])._render_qweb_pdf([id])
if pdf and len(sale_order) > 0:
return rest_api.response_attachment({
'content': pdf,
@@ -205,9 +217,10 @@ class SaleOrder(controller.Controller):
'id': ['number']
})
if not params['valid']:
- return self.response(code=400, description=params)
+ return self.response(code=400, description=params)
- partner_child_ids = self.get_partner_child_ids(params['value']['partner_id'])
+ partner_child_ids = self.get_partner_child_ids(
+ params['value']['partner_id'])
domain = [
('id', '=', params['value']['id']),
('partner_id', 'in', partner_child_ids)
@@ -218,15 +231,19 @@ class SaleOrder(controller.Controller):
sale_order.state = 'cancel'
data = sale_order.id
return self.response(data)
-
+
@http.route(PREFIX_PARTNER + 'sale_order/checkout', auth='public', method=['POST', 'OPTIONS'], csrf=False)
@controller.Controller.must_authorized(private=True, private_key='partner_id')
def create_partner_sale_order(self, **kw):
config = request.env['ir.config_parameter']
- product_pricelist_default_discount_id = int(config.get_param('product.pricelist.default_discount_id'))
- product_pricelist_tier1 = int(config.get_param('product.pricelist.tier1'))
- product_pricelist_tier2 = int(config.get_param('product.pricelist.tier2'))
- product_pricelist_tier3 = int(config.get_param('product.pricelist.tier3'))
+ product_pricelist_default_discount_id = int(
+ config.get_param('product.pricelist.default_discount_id'))
+ product_pricelist_tier1 = int(
+ config.get_param('product.pricelist.tier1'))
+ product_pricelist_tier2 = int(
+ config.get_param('product.pricelist.tier2'))
+ product_pricelist_tier3 = int(
+ config.get_param('product.pricelist.tier3'))
params = self.get_request_params(kw, {
'partner_id': ['number'],
@@ -238,9 +255,10 @@ class SaleOrder(controller.Controller):
'type': [],
'delivery_amount': ['number', 'default:0'],
'carrier_id': [],
- 'delivery_service_type': []
+ 'delivery_service_type': [],
+ 'voucher': []
})
-
+
if not params['valid']:
return self.response(code=400, description=params)
@@ -275,10 +293,12 @@ class SaleOrder(controller.Controller):
order_line = json.loads(params['value']['order_line'])
parameters = []
- partner = request.env['res.partner'].browse(params['value']['partner_id'])
+ partner = request.env['res.partner'].browse(
+ params['value']['partner_id'])
partner_pricelist = partner.property_product_pricelist
for line in order_line:
- product = request.env['product.product'].search([('id', '=', line['product_id'])], limit=1)
+ product = request.env['product.product'].search(
+ [('id', '=', line['product_id'])], limit=1)
discount = product._get_website_disc(0)
price_tier = False
@@ -288,15 +308,19 @@ class SaleOrder(controller.Controller):
'tier3': product._get_pricelist_tier3,
}
partner_pricelist_id = partner_pricelist.id if partner_pricelist else False
- if partner_pricelist_id == product_pricelist_tier1: price_tier = 'tier1'
- if partner_pricelist_id == product_pricelist_tier2: price_tier = 'tier2'
- if partner_pricelist_id == product_pricelist_tier3: price_tier = 'tier3'
+ if partner_pricelist_id == product_pricelist_tier1:
+ price_tier = 'tier1'
+ if partner_pricelist_id == product_pricelist_tier2:
+ price_tier = 'tier2'
+ if partner_pricelist_id == product_pricelist_tier3:
+ price_tier = 'tier3'
if price_tier:
price = pricelist[price_tier]()
discount_key = 'discount_%s' % price_tier
- if price[discount_key] > 0: discount = price[discount_key]
-
+ if price[discount_key] > 0:
+ discount = price[discount_key]
+
flashsale = product._get_flashsale_price()
flashsale_discount = flashsale['flashsale_discount']
if flashsale_discount > 0 and flashsale_discount > discount:
@@ -310,13 +334,29 @@ class SaleOrder(controller.Controller):
'price_unit': product._get_website_price_exclude_tax(),
'discount': discount
})
-
+
request.env['sale.order.line'].create(parameters)
+
+ amount_untaxed = sale_order.amount_untaxed
+ voucher = request.env['voucher'].search([
+ ('code', '=', params['value']['voucher'])
+ ])
+ if voucher:
+ sale_order.voucher_id = voucher.id
+ voucher_discount = voucher.calculate_discount(amount_untaxed)
+ total_qty = sum(line.product_uom_qty for line in sale_order.order_line)
+ voucher_discount_item = voucher_discount / total_qty
+ for line in sale_order.order_line:
+ discount_decimal = line.discount / 100
+ voucher_discount_line = voucher_discount_item / (1 - discount_decimal)
+ price = line.price_unit - voucher_discount_line
+ line.price_unit = price
+
return self.response({
'id': sale_order.id,
'name': sale_order.name
})
-
+
@http.route('/api/sale_order/invoiced', auth='public', methods=['GET'])
def get_sale_order_invoiced_by_partner_id(self, **kw):
if not self.authenticate():
@@ -328,8 +368,10 @@ class SaleOrder(controller.Controller):
partner_id = int(partner_id)
# Get company member by partner_id
- parent_partner_id = request.env['res.partner'].search([('id', '=', partner_id)], limit=1).parent_id.id
- partner_childs = request.env['res.partner'].search([('parent_id', '=', int(parent_partner_id))])
+ parent_partner_id = request.env['res.partner'].search(
+ [('id', '=', partner_id)], limit=1).parent_id.id
+ partner_childs = request.env['res.partner'].search(
+ [('parent_id', '=', int(parent_partner_id))])
partner_child_ids = [v['id'] for v in partner_childs] + [partner_id]
# Get sale order by company member and invoiced
@@ -378,9 +420,12 @@ class SaleOrder(controller.Controller):
('id', '=', id),
('state', 'in', ['sale', 'done'])
]
- parent_partner_id = request.env['res.partner'].search([('id', '=', int(partner_id))], limit=1).parent_id.id
- partner_childs = request.env['res.partner'].search([('parent_id', '=', int(parent_partner_id))])
- partner_child_ids = [v['id'] for v in partner_childs] + [int(partner_id)]
+ parent_partner_id = request.env['res.partner'].search(
+ [('id', '=', int(partner_id))], limit=1).parent_id.id
+ partner_childs = request.env['res.partner'].search(
+ [('parent_id', '=', int(parent_partner_id))])
+ partner_child_ids = [v['id']
+ for v in partner_childs] + [int(partner_id)]
default_domain.append(('partner_id', 'in', partner_child_ids))
sale_order = self.search_filter('sale.order', kw, default_domain)
diff --git a/indoteknik_api/controllers/api_v1/voucher.py b/indoteknik_api/controllers/api_v1/voucher.py
new file mode 100644
index 00000000..0990a1a0
--- /dev/null
+++ b/indoteknik_api/controllers/api_v1/voucher.py
@@ -0,0 +1,22 @@
+from .. import controller
+from odoo import http
+from odoo.http import request
+
+class Voucher(controller.Controller):
+ prefix = '/api/v1/'
+
+ @http.route(prefix + 'voucher', auth='public', methods=['GET', 'OPTIONS'])
+ @controller.Controller.must_authorized()
+ def get_vouchers(self, **kw):
+ code = kw.get('code')
+ visibility = 'public'
+
+ parameter = []
+ if code:
+ visibility = 'private'
+ parameter += [('code', '=', code)]
+
+ parameter += [('visibility', '=', visibility)]
+ vouchers = request.env['voucher'].get_active_voucher(parameter)
+ data = vouchers.res_format()
+ return self.response(data)
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', '&gt;', '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