Commit 7f7e9479 by aa.gusti

BPHTb

1 parent b2869fc2
Showing 65 changed files with 4468 additions and 13 deletions
BPHTB
-----
\ No newline at end of file
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import controllers
from . import models
from . import wizard
from . import report
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': 'BPHTB Kab/Kota',
'version': '0.1',
'summary': 'Pajak & Retribusi Kab/Kota',
'sequence': 10,
'description': """
Pajak & Retribusi
=================
Memudahkan dalam mengelola tagihan kepada wajib pajak atau wajib retribusi
""",
'category': 'Indonesia Goverment',
'website': 'https://opensipkd.com',
'images': [],
'depends': ['id_gov'],
'data': [
'security/account_security.xml',
'security/ir.model.access.csv',
'security/ir_rule.xml',
'data/bphtb.jenis.csv',
'data/res_user.xml',
'views/jenis.xml',
'views/partner.xml',
'views/sales.xml',
'views/menus.xml',
'demo/bphtb.sales.csv',
],
'demo': [
'demo/bphtb.sales.csv'
],
'qweb': [],
'installable': True,
'application': True,
'auto_install': False,
'license': 'LGPL-3',
'module': 'pajak'
}
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import onboarding
from . import portal
from odoo import http
from odoo.http import request
class OnboardingController(http.Controller):
@http.route('/pad/pad_invoice_onboarding', auth='user', type='json')
def pad_invoice_onboarding(self):
""" Returns the `banner` for the pad invoice onboarding panel.
It can be empty if the user has closed it or if he doesn't have
the permission to see it. """
company = request.env.company
if not request.env.is_admin() or \
company.pad_invoice_onboarding_state == 'closed':
return {}
return {
'html': request.env.ref('pad.pad_invoice_onboarding_panel')._render({
'company': company,
'state': company.get_and_update_pad_invoice_onboarding_state()
})
}
@http.route('/pad/pad_dashboard_onboarding', auth='user', type='json')
def pad_dashboard_onboarding(self):
""" Returns the `banner` for the pad dashboard onboarding panel.
It can be empty if the user has closed it or if he doesn't have
the permission to see it. """
company = request.env.company
if not request.env.is_admin() or \
company.pad_dashboard_onboarding_state == 'closed':
return {}
return {
'html': request.env.ref('pad.pad_dashboard_onboarding_panel')._render({
'company': company,
'state': company.get_and_update_pad_dashboard_onboarding_state()
})
}
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import http, _
from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager
from odoo.exceptions import AccessError, MissingError
from collections import OrderedDict
from odoo.http import request
class PortalAccount(CustomerPortal):
def _prepare_home_portal_values(self, counters):
values = super()._prepare_home_portal_values(counters)
if 'invoice_count' in counters:
invoice_count = request.env['account.move'].search_count(self._get_pad_domain()) \
if request.env['account.move'].check_access_rights('read', raise_exception=False) else 0
values['invoice_count'] = invoice_count
return values
# ------------------------------------------------------------
# My pad
# ------------------------------------------------------------
def _invoice_get_page_view_values(self, invoice, access_token, **kwargs):
values = {
'page_name': 'invoice',
'invoice': invoice,
}
return self._get_page_view_values(invoice, access_token, values, 'my_pad_history', False, **kwargs)
def _get_pad_domain(self):
return [
('move_type', 'in', ('out_invoice', 'out_refund', 'in_invoice', 'in_refund', 'out_receipt', 'in_receipt'))]
@http.route(['/my/pad', '/my/pad/page/<int:page>'], type='http', auth="user", website=True)
def portal_my_pad(self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, **kw):
values = self._prepare_portal_layout_values()
AccountInvoice = request.env['account.move']
domain = self._get_pad_domain()
searchbar_sortings = {
'date': {'label': _('Date'), 'order': 'invoice_date desc'},
'duedate': {'label': _('Due Date'), 'order': 'invoice_date_due desc'},
'name': {'label': _('Reference'), 'order': 'name desc'},
'state': {'label': _('Status'), 'order': 'state'},
}
# default sort by order
if not sortby:
sortby = 'date'
order = searchbar_sortings[sortby]['order']
searchbar_filters = {
'all': {'label': _('All'), 'domain': []},
'pad': {'label': _('pad'), 'domain': [('move_type', '=', ('out_invoice', 'out_refund'))]},
'bills': {'label': _('Bills'), 'domain': [('move_type', '=', ('in_invoice', 'in_refund'))]},
}
# default filter by value
if not filterby:
filterby = 'all'
domain += searchbar_filters[filterby]['domain']
if date_begin and date_end:
domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)]
# count for pager
invoice_count = AccountInvoice.search_count(domain)
# pager
pager = portal_pager(
url="/my/pad",
url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby},
total=invoice_count,
page=page,
step=self._items_per_page
)
# content according to pager and archive selected
pad = AccountInvoice.search(domain, order=order, limit=self._items_per_page, offset=pager['offset'])
request.session['my_pad_history'] = pad.ids[:100]
values.update({
'date': date_begin,
'pad': pad,
'page_name': 'invoice',
'pager': pager,
'default_url': '/my/pad',
'searchbar_sortings': searchbar_sortings,
'sortby': sortby,
'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
'filterby': filterby,
})
return request.render("account.portal_my_pad", values)
@http.route(['/my/pad/<int:invoice_id>'], type='http', auth="public", website=True)
def portal_my_invoice_detail(self, invoice_id, access_token=None, report_type=None, download=False, **kw):
try:
invoice_sudo = self._document_check_access('account.move', invoice_id, access_token)
except (AccessError, MissingError):
return request.redirect('/my')
if report_type in ('html', 'pdf', 'text'):
return self._show_report(model=invoice_sudo, report_type=report_type, report_ref='account.account_pad',
download=download)
values = self._invoice_get_page_view_values(invoice_sudo, access_token, **kw)
acquirers = values.get('acquirers')
if acquirers:
country_id = values.get('partner_id') and values.get('partner_id')[0].country_id.id
values['acq_extra_fees'] = acquirers.get_acquirer_extra_fees(invoice_sudo.amount_residual,
invoice_sudo.currency_id, country_id)
return request.render("account.portal_invoice_page", values)
# ------------------------------------------------------------
# My Home
# ------------------------------------------------------------
def details_form_validate(self, data):
error, error_message = super(PortalAccount, self).details_form_validate(data)
# prevent VAT/name change if pad exist
partner = request.env['res.users'].browse(request.uid).partner_id
if not partner.can_edit_vat():
if 'vat' in data and (data['vat'] or False) != (partner.vat or False):
error['vat'] = 'error'
error_message.append(
_('Changing VAT number is not allowed once pad have been issued for your account. Please contact '
'us directly for this operation.'))
if 'name' in data and (data['name'] or False) != (partner.name or False):
error['name'] = 'error'
error_message.append(
_('Changing your name is not allowed once pad have been issued for your account. Please contact '
'us directly for this operation.'))
if 'company_name' in data and (data['company_name'] or False) != (partner.company_name or False):
error['company_name'] = 'error'
error_message.append(
_('Changing your company name is not allowed once pad have been issued for your account. Please contact us directly for this operation.'))
return error, error_message
id,code,name,min_omzet,rate,disc,company_id:id,under_value
bphtb_01,01,Jual Beli,60000000,5,0,base.main_company,False
bphtb_02,02,Tukar Menukar,60000000,5,0,base.main_company,False
bphtb_03,03,Hibah,60000000,5,0,base.main_company,False
bphtb_04,04,Hibah Wasiat,300000000,5,50,base.main_company,False
bphtb_05,05,Waris,300000000,5,50,base.main_company,False
bphtb_06,06,Pemasukan dalam Perseroan atau Badan Hukum Lainnya,60000000,5,0,base.main_company,False
bphtb_07,07,Pemisahan Hak yang mengakibatkan Peralihan,60000000,5,0,base.main_company,False
bphtb_08,08,Penunjukan Pembelli dalam Lelang,60000000,5,0,base.main_company,True
bphtb_09,09,Pelaksanaan Putusan Hakim yang mempunyai kekuatan hukum tetap,60000000,5,0,base.main_company,True
bphtb_10,10,Penggabungan Usaha,60000000,5,0,base.main_company,False
bphtb_11,11,Peleburan Usaha,60000000,5,0,base.main_company,False
bphtb_12,12,Pemekaran Usaha,60000000,5,0,base.main_company,False
bphtb_13,13,Hadiah,60000000,5,0,base.main_company,False
bphtb_14,14,Perolehan hak Rumah Sederhana Sehat dan RSS melalui KPR bersubsidi,60000000,5,0,base.main_company,False
bphtb_15,15,Pemberian Hak Baru Kelanjutan Pelepasan Hak,60000000,5,0,base.main_company,False
bphtb_16,16,Pemberian hak baru diluar pelepasan hak,60000000,5,0,base.main_company,False
bphtb_17,17,Tax Amnesti,60000000,5,0,base.main_company,False
bphtb_18,18,Peningkatan Status,0,0,0,base.main_company,False
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="bphtb_partner_admin_kab_id" model="res.partner">
<field name="name">Admin BPHTB Kab/Kota</field>
<field name="street">Jalan-jalan</field>
<field name="country_id" ref="base.id"/>
<field name="state_id" ref="base.state_id_jb"/>
<field name="district_id" ref="id_gov.ct_jb_71"/>
<field name="company_id" ref="base.main_company"/>
<field name="zip">90241</field>
<field name="phone">+62 812-345-678</field>
<field name="email">info@company.idexample.com</field>
<field name="website">www.idexample.com</field>
</record>
<record id="bphtb_user_admin_kab_id" model="res.users">
<field name="login">bphtb_admin</field>
<field name="password">admin</field>
<field name="partner_id" ref="bphtb_partner_admin_kab_id"/>
<field name="company_id" ref="base.main_company"/>
<field name="company_ids" eval="[(4,ref('base.main_company'))]"/>
<field name="groups_id"
eval="[(6,0,[ref('base.group_user'), ref('bphtb_kab.group_bphtb_admin')])]"/>
</record>
<record id="bphtb_partner_ppat_kab_id" model="res.partner">
<field name="name">PPAT Kab/Kota</field>
<field name="street">Jalan-jalan</field>
<field name="country_id" ref="base.id"/>
<field name="state_id" ref="base.state_id_jb"/>
<field name="district_id" ref="id_gov.ct_jb_71"/>
<field name="company_id" ref="base.main_company"/>
<field name="zip">90241</field>
<field name="type">ppat</field>
<field name="phone">+62 812-345-678</field>
<field name="email">info@company.idexample.com</field>
<field name="website">www.idexample.com</field>
</record>
<record id="bphtb_user_ppat_kab_id" model="res.users">
<field name="login">ppat</field>
<field name="password">ppat</field>
<field name="partner_id" ref="bphtb_partner_ppat_kab_id"/>
<field name="company_id" ref="base.main_company"/>
<field name="company_ids" eval="[(4,ref('base.main_company'))]"/>
<field name="groups_id"
eval="[(6,0,[ref('base.group_user'), ref('bphtb_kab.group_bphtb_ppat')])]"/>
</record>
<record id="bphtb_partner_wp_kab_id" model="res.partner">
<field name="name">Wajib Pajak BPHTB</field>
<field name="street">Jalan-jalan</field>
<field name="country_id" ref="base.id"/>
<field name="state_id" ref="base.state_id_jb"/>
<field name="district_id" ref="id_gov.ct_jb_71"/>
<field name="company_id" ref="base.main_company"/>
<field name="zip">90241</field>
<field name="type">wp</field>
<field name="phone">+62 812-345-678</field>
<field name="email">info@company.idexample.com</field>
<field name="website">www.idexample.com</field>
</record>
<record id="bphtb_partner_penjual_kab_id" model="res.partner">
<field name="name">Wajib Pajak Penjual BPHTB</field>
<field name="street">Jalan-jalan</field>
<field name="country_id" ref="base.id"/>
<field name="state_id" ref="base.state_id_jb"/>
<field name="district_id" ref="id_gov.ct_jb_71"/>
<field name="company_id" ref="base.main_company"/>
<field name="zip">90241</field>
<field name="type">wp</field>
<field name="phone">+62 812-345-678</field>
<field name="email">info@company.idexample.com</field>
<field name="website">www.idexample.com</field>
</record>
</data>
</odoo>
\ No newline at end of file
id,ppat_id:id,wp_id:id,seller_id:id,state,nop,tax_year,luas_bumi,luas_bng,njop_bumi,njop_bng,luas_bumi_bersama,luas_bng_bersama,njop_bumi_bersama,njop_bng_bersama,jenis_id:id,rate,min_omzet,disc_sk,npop,basic,fine,amount,disc_amount,owed,typ,company_id:id,certicate_no
sspd_01,bphtb_partner_ppat_kab_id,bphtb_partner_wp_kab_id,bphtb_partner_penjual_kab_id,draft,367601000100100010,2021,100,50,500000000,250000000,0,0,00,0,bphtb_01,5,60000000,,1000000000,0,0,0,0,0,sspd,base.main_company,-
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="pdl_partner_company_id" model="res.partner">
<field name="name">Kabupaten/Kota</field>
<field name="street">Jalan-jalan</field>
<field name="country_id" ref="base.id"/>
<field name="state_id" ref="base.state_id_jb"/>
<field name="district_id" ref="id_gov.ct_jb_71"/>
<field name="zip">90241</field>
<field name="phone">+62 812-345-678</field>
<field name="email">info@company.idexample.com</field>
<field name="website">www.idexample.com</field>
</record>
<record id="pdl_company_id" model="res.company">
<field name="name">Kabupaten/Kota Company</field>
<field name="partner_id" ref="pdl_partner_company_id"/>
</record>
</data>
<data>
<function model="res.users" name="write">
<value eval="[ref('base.user_root'), ref('base.user_admin'), ref('base.user_demo')]"/>
<value eval="{'company_ids': [(4, ref('pdl_kab.pdl_company_id'))]}"/>
</function>
</data>
</odoo>
\ No newline at end of file
from . import bphtb_ref
from . import partner
from . import sales
\ No newline at end of file
from sqlite3 import DatabaseError
from odoo import api, fields, models, _
from psycopg2 import sql, DatabaseError
import logging
_logger = logging.getLogger(__name__)
class BphtbJenis(models.Model):
_name = 'bphtb.jenis'
_description = 'Jenis BPHTB'
code = fields.Char(index=True, string='Code')
name = fields.Char(index=True, string='Name', size=64)
rate = fields.Float(required=True, default=5)
disc = fields.Float(required=True, default=0)
min_omzet = fields.Float(required=True, default=60000000)
under_value = fields.Boolean(required=True, default=False)
company_id = fields.Many2one('res.company',
default=lambda self: self.env.company.id
if not self.company_id else False)
_sql_constraints = [
('company_code_uniq', 'unique (company_id, code)', 'Kode harus unik')
]
from odoo import fields, models, api
class ResPartner(models.Model):
_inherit = 'res.partner'
supplier_rank = fields.Integer(default=0)
customer_rank = fields.Integer(default=0)
company_id = fields.Many2one(
'res.company', string="Company",
default=lambda self: self.env.company.id
if not self.company_id else False)
type = fields.Selection(
selection_add=[('ppat', 'PPAT'),
('wp', 'Wajib Pajak')],
ondelete={
'ppat': 'cascade',
'wp': 'cascade',
})
from sqlite3 import DatabaseError
from odoo import api, fields, models, _
from psycopg2 import sql, DatabaseError
import logging
_logger = logging.getLogger(__name__)
class BphtbSales(models.Model):
_name = 'bphtb.sales'
_description = 'Transaksi BPHTB'
# code = fields.Char(index=True, string='Code')
# name = fields.Char(index=True, string='Name', size=64)
#
# rate = fields.Float(required=True)
# disc = fields.Float(required=True)
# min_omzet = fields.Integer(required=True)
request_date = fields.Date()
ppat_id = fields.Many2one('res.partner',
default=lambda self: self.env.user.partner_id.id
if not self.ppat_id else False)
wp_id = fields.Many2one('res.partner')
wp_name = fields.Char(related='wp_id.name', string="Wajib Pajak", store=True)
wp_identity_number = fields.Char(related='wp_id.identity_number',
string="No Identitas", store=True)
wp_street = fields.Char(compute='_compute_wp', store=False)
wp_street2 = fields.Char(compute='_compute_wp', store=False)
wp_village_id = fields.Many2one('res.district.village', compute='_compute_wp', store=False,
string="WP Desa/Kelurahan")
wp_sub_district_id = fields.Many2one('res.district.sub', compute='_compute_wp',
store=False, string="WP Kecamatan")
wp_district_id = fields.Many2one('res.district', compute='_compute_wp',
store=False, string="WP Kota/Kab")
wp_state_id = fields.Many2one('res.country.state', compute='_compute_wp',
store=False, string="WP Provinsi")
wp_zip = fields.Char(compute='_compute_wp', string="WP ZIP", store=False)
wp_phone = fields.Char(compute='_compute_wp', string="WP Phone", store=False)
wp_email = fields.Char(compute='_compute_wp', string="WP Email", store=False)
wp_website = fields.Char(compute='_compute_wp', string="WP Web Site", store=False)
seller_id = fields.Many2one('res.partner')
seller_name = fields.Char(related='wp_id.name', string="Wajib Pajak", store=True)
seller_identity_number = fields.Char(related='wp_id.identity_number',
string="No Identitas", store=True)
seller_street = fields.Char(compute='_compute_seller', store=False)
seller_street2 = fields.Char(compute='_compute_seller', store=False)
seller_village_id = fields.Many2one('res.district.village', compute='_compute_seller', store=False,
string="WP Desa/Kelurahan")
seller_sub_district_id = fields.Many2one('res.district.sub', compute='_compute_seller',
store=False, string="Penjual Kecamatan")
seller_district_id = fields.Many2one('res.district', compute='_compute_seller',
store=False, string="Penjual Kota/Kab")
seller_state_id = fields.Many2one('res.country.state', compute='_compute_seller',
store=False, string="Penjual Provinsi")
seller_zip = fields.Char(compute='_compute_seller', string="Penjual ZIP", store=False)
seller_phone = fields.Char(compute='_compute_seller', string="Penjual Phone", store=False)
seller_email = fields.Char(compute='_compute_seller', string="Penjual Email", store=False)
seller_website = fields.Char(compute='_compute_seller', string="Penjual Web Site", store=False)
state = fields.Char(default='draft') # 0 draft - 1 posted - 2 batal
nop = fields.Char(size=18)
tax_year = fields.Integer()
# kd_propinsi = Column(String(2), nullable=False)
# kd_dati2 = Column(String(2), nullable=False)
# kd_kecamatan = Column(String(3), nullable=False)
# kd_kelurahan = Column(String(3), nullable=False)
# kd_blok = Column(String(3), nullable=False)
# no_urut = Column(String(4), nullable=False)
# kd_jns_op = Column(String(1), nullable=False)
# op_alamat = Column(String(128), nullable=False)
# op_blok_kav = Column(String(128), nullable=False)
# op_rt = Column(String(3), nullable=False)
# op_rw = Column(String(3), nullable=False)
luas_bumi = fields.Float()
luas_bng = fields.Float()
njop_bumi = fields.Float()
njop_bng = fields.Float()
luas_bumi_bersama = fields.Float()
luas_bng_bersama = fields.Float()
njop_bumi_bersama = fields.Float()
njop_bng_bersama = fields.Float()
certicate_no = fields.Char(required=True)
njop = fields.Float(compute="_compute_njop", store=True)
jenis_id = fields.Many2one('bphtb.jenis')
rate = fields.Float(related='jenis_id.rate', store=True, readonly=True)
min_omzet = fields.Float(related='jenis_id.min_omzet', store=True, readonly=True)
disc_sk = fields.Char(required=False)
disc = fields.Float(related='jenis_id.disc', store=True, readonly=True)
npop = fields.Float()
basic_calc = fields.Float(compute="_compute_basic_calc")
basic = fields.Float()
fine = fields.Float()
amount = fields.Float()
disc_amount = fields.Float()
payment = fields.Float()
owed = fields.Float(compute="_compute_owed")
typ = fields.Selection([
('sspd', 'SSPD'),
('kb', 'SKPD KB'),
('kbt', 'SKPD KBT'),
('lb', 'SKPD LB'),
('nihil', 'SKPD Nihil'),
])
# file01 = Column(String(128))
# file02 = Column(String(128))
# file03 = Column(String(128))
# file04 = Column(String(128))
# file05 = Column(String(128))
# file06 = Column(String(128))
# file07 = Column(String(128))
# file08 = Column(String(128))
# file09 = Column(String(128))
# file10 = Column(String(128))
verification_date = fields.Date()
verification_no = fields.Char()
verification_uid = fields.Integer()
company_id = fields.Many2one('res.company',
default=lambda self: self.env.company.id
if not self.company_id else False)
# _sql_constraints = [
# ('company_code_uniq', 'unique (company_id, code)', 'Kode harus unik')
# ]
# Prosesing Wajib Pajak
def _get_wp_field_names(self):
return [
("wp_identity_number", "identity_number"),
("wp_street", "street"),
("wp_street2", "street2"),
("wp_village_id", "village_id"),
("wp_sub_district_id", "sub_district_id"),
("wp_district_id", "district_id"),
("wp_state_id", "state_id"),
("wp_phone", "phone"),
("wp_email", "email"),
("wp_website", "website"),
("wp_zip", "zip"),
]
def _get_wp_update(self, partner):
if partner:
field = dict((key, partner[value])
for key, value in self._get_wp_field_names())
else:
field = dict((key, False)
for key, value in self._get_wp_address_field_names())
return field
def _compute_wp(self):
if self.wp_id:
for bphtb_sales in self.filtered(lambda bphtb_sales: bphtb_sales.wp_id):
address_data = bphtb_sales.wp_id.sudo().address_get(adr_pref=['wp'])
if address_data['wp']:
partner = bphtb_sales.wp_id.browse(address_data['wp']).sudo()
bphtb_sales.update(bphtb_sales._get_wp_update(partner))
else:
bphtb_sales.update(bphtb_sales._get_wp_update(False))
else:
self.update(self._get_wp_update(False))
# Seller
def _get_seller_field_names(self):
return [
("seller_identity_number", "identity_number"),
("seller_street", "street"),
("seller_street2", "street2"),
("seller_village_id", "village_id"),
("seller_sub_district_id", "sub_district_id"),
("seller_district_id", "district_id"),
("seller_state_id", "state_id"),
("seller_phone", "phone"),
("seller_email", "email"),
("seller_website", "website"),
("seller_zip", "zip"),
]
def _get_seller_update(self, partner):
if partner:
field = dict((key, partner[value])
for key, value in self._get_seller_field_names())
else:
field = dict((key, False)
for key, value in self._get_seller_address_field_names())
return field
def _compute_seller(self):
if self.seller_id:
for bphtb_sales in self.filtered(lambda bphtb_sales: bphtb_sales.seller_id):
address_data = bphtb_sales.seller_id.sudo().address_get(adr_pref=['wp'])
if address_data['wp']:
partner = bphtb_sales.seller_id.browse(address_data['wp']).sudo()
bphtb_sales.update(bphtb_sales._get_seller_update(partner))
else:
bphtb_sales.update(bphtb_sales._get_seller_update(False))
else:
self.update(self._get_seller_update(False))
@api.depends('njop', 'npop', 'min_omzet')
def _compute_basic_calc(self):
if self.npop < self.njop and self.jenis_id.under_value:
self.basic_calc = self.npop
else:
self.basic_calc = self.npop if self.npop > self.njop else self.njop
@api.depends('disc', 'payment', 'basic_calc')
def _compute_owed(self):
self.basic = (self.basic_calc - self.min_omzet)* self.rate / 100
self.amount = self.basic + self.fine
self.disc_amount = self.disc / 100 * self.amount
self.owed = self.amount - self.disc_amount - self.payment
@api.depends('njop_bumi_bersama', 'njop_bng_bersama', 'njop_bumi', 'njop_bng')
def _compute_njop(self):
self.njop = self.njop_bng + self.njop_bumi + self.njop_bumi_bersama + \
self.njop_bng_bersama
# @api.depends('njop')
# def njop_change(self):
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="report_product_label" model="ir.actions.report">
<field name="name">Product Label (PDF)</field>
<field name="model">product.product</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">product.report_productlabel</field>
<field name="report_file">product.report_productlabel</field>
<field name="print_report_name">'Products Labels - %s' % (object.name)</field>
<!-- <field name="binding_model_id" ref="product.model_product_product"/>-->
<field name="binding_type">report</field>
<field name="binding_model_id" eval="False"/>
</record>
<record id="report_product_template_label" model="ir.actions.report">
<field name="name">Product Label (PDF)</field>
<field name="model">product.template</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">product.report_producttemplatelabel</field>
<field name="report_file">product.report_producttemplatelabel</field>
<field name="print_report_name">'Products Labels - %s' % (object.name)</field>
<field name="binding_model_id" eval="False"/>
<!-- <field name="binding_model_id" ref="product.model_product_template"/>-->
<field name="binding_type">report</field>
</record>
<record id="report_product_product_barcode" model="ir.actions.report">
<field name="name">Product Barcode (PDF)</field>
<field name="model">product.product</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">product.report_productbarcode</field>
<field name="report_file">product.report_productbarcode</field>
<field name="print_report_name">'Products barcode - %s' % (object.name)</field>
<field name="binding_model_id" eval="False"/>
<!-- <field name="binding_model_id" ref="product.model_product_product"/>-->
<field name="binding_type">report</field>
</record>
<record id="report_product_template_barcode" model="ir.actions.report">
<field name="name">Product Barcode (PDF)</field>
<field name="model">product.template</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">product.report_producttemplatebarcode</field>
<field name="report_file">product.report_producttemplatebarcode</field>
<field name="print_report_name">'Products barcode - %s' % (object.name)</field>
<field name="binding_model_id" eval="False"/>
<!-- <field name="binding_model_id" ref="product.model_product_template"/>-->
<field name="binding_type">report</field>
</record>
<record id="report_product_packaging" model="ir.actions.report">
<field name="name">Product Packaging (PDF)</field>
<field name="model">product.packaging</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">product.report_packagingbarcode</field>
<field name="report_file">product.report_packagingbarcode</field>
<field name="print_report_name">'Products packaging - %s' % (object.name)</field>
<field name="binding_model_id" eval="False"/>
<!-- <field name="binding_model_id" ref="product.model_product_packaging"/>-->
<field name="binding_type">report</field>
</record>
<record id="action_report_pricelist" model="ir.actions.report">
<field name="name">Pricelist</field>
<field name="model">product.product</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">product.report_pricelist</field>
<field name="report_file">product.report_pricelist</field>
<field name="binding_model_id" eval="False"/>
</record>
</data>
</odoo>
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="0">
<record model="ir.module.category" id="bphtb">
<field name="name">BPHTB</field>
<field name="description">BPHTB</field>
<field name="sequence">1</field>
</record>
<record id="group_bphtb_admin" model="res.groups">
<field name="name">Administrator</field>
<field name="category_id" ref="bphtb"/>
</record>
<record id="group_bphtb_ppat" model="res.groups">
<field name="name">PPAT</field>
<field name="category_id" ref="bphtb"/>
</record>
</data>
</odoo>
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_bphtb_jenis_admin","access.bphtb.jenis.admin","model_bphtb_jenis","base.group_system",1,1,1,1
"access_bphtb_jenis_bphtb_admin","access.bphtb.jenis.bphtb.admin","model_bphtb_jenis","group_bphtb_admin",1,1,1,1
"access_bphtb_jenis_bphtb_ppat","access.bphtb.jenis.bphtb.ppat","model_bphtb_jenis","group_bphtb_ppat",1,0,0,0
"access_district_bphtb_admin","access.district.bphtb.admin","id_gov.model_res_district","group_bphtb_admin",1,1,1,1
"access_district_sub_bphtb_admin","access.district.sub.bphtb.admin","id_gov.model_res_district_sub","group_bphtb_admin",1,1,1,1
"access_village_bphtb_admin","access.village.bphtb.admin","id_gov.model_res_district_village","group_bphtb_admin",1,1,1,1
"access_jenis_bphtb_admin","access.bphtb.jenis.bphtb.admin","model_bphtb_jenis","group_bphtb_admin",1,1,1,1
"access_bphtb_sales_admin","access.bphtb.sales.admin","model_bphtb_sales","base.group_system",1,1,1,1
"access_bphtb_sales_bphtb_admin","access.bphtb.sales.bphtb.admin","model_bphtb_sales","group_bphtb_admin",1,1,1,1
"access_bphtb_sales_bphtb_ppat","access.bphtb.sales.bphtb.ppt","model_bphtb_sales","group_bphtb_ppat",1,1,1,0
<?xml version="1.0"?>
<odoo>
<data noupdate="0">
</data>
</odoo>
\ No newline at end of file
.o_form_view {
background-color: white;
}
.o_form_view .oe_form_box_info {
padding-top: 5px;
padding-right: 16px;
padding-bottom: 5px;
padding-left: 16px;
}
.o_form_view .oe_form_box_info > p {
margin: auto;
}
.o_form_view .oe_text_center {
text-align: center;
}
.o_form_view .oe_grey {
opacity: 0.5;
}
.o_form_view .oe_inline, .o_form_view .oe_right, .o_form_view .o_group.o_inner_group.oe_subtotal_footer, .o_form_view .oe_left {
width: auto !important;
}
@media (min-width: 475px) {
.o_form_view .oe_inline.o_inner_group, .o_form_view .o_inner_group.oe_right, .o_form_view .o_inner_group.o_group.oe_subtotal_footer, .o_form_view .o_inner_group.oe_left {
width: 1px !important;
}
}
.o_form_view .oe_left {
float: left !important;
}
.o_form_view .oe_right, .o_form_view .o_group.o_inner_group.oe_subtotal_footer {
float: right !important;
}
@media (min-width: 475px) {
.o_form_view .o_row {
align-items: baseline;
min-width: 50px;
margin: 0 -2.5px;
}
.o_form_view .o_row, .o_form_view .o_row.o_field_widget {
display: -webkit-box;
display: -webkit-flex;
display: flex;
width: auto !important;
}
.o_form_view .o_row > div, .o_form_view .o_row > span, .o_form_view .o_row > button, .o_form_view .o_row > label, .o_form_view .o_row > a, .o_form_view .o_row > input, .o_form_view .o_row > select {
-webkit-box-flex: 0;
-webkit-flex: 0 0 auto;
flex: 0 0 auto;
width: auto !important;
margin-right: 2.5px;
margin-left: 2.5px;
}
.o_form_view .o_row > .o_row {
margin: 0;
}
.o_form_view .o_row > .btn {
padding-top: 0;
padding-bottom: 0;
}
.o_form_view .o_row > .o_field_boolean {
align-self: center;
}
}
.o_form_view .o_row > div > .o_field_widget {
width: 100%;
}
.o_form_view.o_form_readonly .oe_edit_only {
display: none !important;
}
.o_form_view.o_form_readonly .o_row:not(.o_row_readonly), .o_form_view.o_form_readonly .o_row:not(.o_row_readonly) > div {
display: inline-block;
}
.o_form_view.o_form_readonly .o_field_color_picker_preview > li > a {
cursor: default;
}
.o_form_view .o_form_uri {
display: inline-block;
color: #7C7BAD;
}
.o_form_view .o_form_uri:hover {
color: #555487;
}
.o_form_view .o_form_uri > span {
color: #4c4c4c;
}
.o_form_view .o_form_uri > span:hover {
color: #4c4c4c;
}
.o_form_view .o_form_uri > span:first-child {
color: #7C7BAD;
}
.o_form_view .o_form_uri > span:first-child:hover {
color: #555487;
}
.o_form_view.o_form_editable .oe_read_only {
display: none !important;
}
.o_form_view.o_form_editable .oe_title {
max-width: 688px;
}
@media (min-width: 475px) {
.o_form_view.o_form_editable .o_row > .o_field_widget, .o_form_view.o_form_editable .o_row > div {
-webkit-box-flex: 1;
-webkit-flex: 1 1 auto;
flex: 1 1 auto;
width: 0 !important;
}
.o_form_view.o_form_editable .o_row > .o_field_widget.o_field_boolean, .o_form_view.o_form_editable .o_row > .o_field_widget.o_priority, .o_form_view.o_form_editable .o_row > div.o_field_boolean, .o_form_view.o_form_editable .o_row > div.o_priority {
-webkit-box-flex: 0;
-webkit-flex: 0 0 auto;
flex: 0 0 auto;
width: auto !important;
}
}
.o_form_view.o_form_nosheet {
display: block;
padding-top: 24px;
padding-right: 16px;
padding-bottom: 24px;
padding-left: 16px;
}
.o_form_view.o_form_nosheet .o_form_statusbar {
margin: -24px -16px 24px -16px;
}
.o_form_view .o_form_sheet_bg {
position: relative;
}
.o_form_view .o_form_statusbar {
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: flex;
justify-content: space-between;
padding-left: 16px;
border-bottom: 1px solid #ced4da;
background-color: white;
}
.o_form_view .o_form_statusbar > .o_statusbar_buttons, .o_form_view .o_form_statusbar > .o_statusbar_status {
display: -webkit-box;
display: -webkit-flex;
display: flex;
align-items: center;
align-content: space-around;
}
.o_form_view .o_form_statusbar > .o_field_widget {
align-self: center;
margin-bottom: 0px;
}
.o_form_view .o_form_statusbar > .o_statusbar_buttons {
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
}
.o_form_view .o_form_statusbar > .o_statusbar_buttons > .btn {
min-height: 25px;
margin: 4px 3px 4px 0;
padding-top: 2px;
padding-bottom: 2px;
}
.o_form_view .o_form_statusbar > .o_statusbar_status {
margin-left: auto;
flex-flow: row-reverse wrap-reverse;
align-self: stretch;
align-items: stretch;
}
.o_form_view .o_form_statusbar > .o_statusbar_status > .o_arrow_button {
min-height: 33px;
font-size: 11px;
font-weight: bold;
position: relative;
padding-left: 22px;
color: #495057;
border-width: 0 0 0;
border-radius: 0;
transition: all 0.1s ease 0s;
}
.o_form_view .o_form_statusbar > .o_statusbar_status > .o_arrow_button:first-child {
padding-right: 16px;
overflow-x: hidden;
}
.o_form_view .o_form_statusbar > .o_statusbar_status > .o_arrow_button:last-child {
padding-left: 15px;
border-left: 1px solid #ced4da;
}
.o_form_view .o_form_statusbar > .o_statusbar_status > .o_arrow_button:active {
box-shadow: none;
}
.o_form_view .o_form_statusbar > .o_statusbar_status > .o_arrow_button.disabled {
opacity: 1.0;
color: #adb5bd;
pointer-events: none;
border-left: 1px solid #dee2e6;
}
.o_form_view .o_form_statusbar > .o_statusbar_status > .o_arrow_button:not(:first-child):before, .o_form_view .o_form_statusbar > .o_statusbar_status > .o_arrow_button:not(:first-child):after {
content: " ";
display: block;
position: absolute;
top: 0;
left: auto;
bottom: auto;
right: -10px;
border-top: 16px solid transparent;
border-bottom: 17px solid transparent;
border-right: none;
border-left: 11px solid white;
transition: border 0.2s ease 0s;
-moz-transform: scale(0.9999);
}
.o_form_view .o_form_statusbar > .o_statusbar_status > .o_arrow_button:not(.disabled):hover, .o_form_view .o_form_statusbar > .o_statusbar_status > .o_arrow_button:not(.disabled):active, .o_form_view .o_form_statusbar > .o_statusbar_status > .o_arrow_button:not(.disabled):focus {
color: #7C7BAD;
background-color: #e9ecef;
}
.o_form_view .o_form_statusbar > .o_statusbar_status > .o_arrow_button:not(.disabled):hover:after, .o_form_view .o_form_statusbar > .o_statusbar_status > .o_arrow_button:not(.disabled):active:after, .o_form_view .o_form_statusbar > .o_statusbar_status > .o_arrow_button:not(.disabled):focus:after {
border-left-color: #e9ecef;
}
.o_form_view .o_form_statusbar > .o_statusbar_status > .o_arrow_button:not(:first-child):before {
right: -11px;
border-left-color: #dee2e6;
}
.o_form_view .o_form_statusbar > .o_statusbar_status > .o_arrow_button.btn-primary.disabled {
color: #7C7BAD;
font-size: 11px;
background-color: #e9ecef;
cursor: default;
}
.o_form_view .o_form_statusbar > .o_statusbar_status > .o_arrow_button.btn-primary.disabled:after {
border-left-color: #e9ecef;
}
.o_form_view .o_form_statusbar > .o_statusbar_buttons > .btn-group > .dropdown-toggle:after, .o_form_view .o_form_statusbar > .o_statusbar_status > .dropdown-toggle:after {
content: "";
display: inline-block;
width: 0;
height: 0;
vertical-align: middle;
border-bottom: 0;
border-left: 0.3em solid transparent;
border-right: 0.3em solid transparent;
border-top: 0.3em solid;
-moz-transform: scale(0.9999);
margin-left: 5px;
}
.o_form_view .o_form_statusbar > .o_statusbar_buttons > .btn-group > .dropdown-menu, .o_form_view .o_form_statusbar > .o_statusbar_status > .dropdown-menu {
padding: 5px 0 2px 0;
min-width: 100px;
}
.o_form_view .o_form_statusbar > .o_statusbar_buttons > .btn-group > .dropdown-menu .dropdown-item.btn, .o_form_view .o_form_statusbar > .o_statusbar_status > .dropdown-menu .dropdown-item.btn {
min-width: 100%;
margin-bottom: 3px;
}
.o_form_view .oe_button_box {
position: relative;
display: block;
margin-bottom: 24px;
margin-top: -24px;
margin-left: -16px;
margin-right: -16px;
text-align: right;
box-shadow: inset 0 -1px 0 #ced4da;
}
@media (min-width: 992px) and (max-width: 1533.98px) {
.o_form_view .oe_button_box {
margin-left: -32px;
margin-right: -32px;
}
}
.o_form_view .oe_button_box.o_full .oe_stat_button:not(.o_invisible_modifier) ~ .oe_stat_button {
border-left: 1px solid #ced4da;
}
.o_form_view .oe_button_box.o_not_full .oe_stat_button {
border-left: 1px solid #ced4da;
}
.o_form_view .oe_button_box > .btn.oe_stat_button, .o_form_view .oe_button_box > .o_dropdown_more {
-webkit-box-flex: 0;
-webkit-flex: 0 0 auto;
flex: 0 0 auto;
width: 33.33333333%;
}
@media (min-width: 768px) {
.o_form_view .oe_button_box > .btn.oe_stat_button, .o_form_view .oe_button_box > .o_dropdown_more {
width: 20%;
}
}
@media (min-width: 992px) {
.o_form_view .oe_button_box > .btn.oe_stat_button, .o_form_view .oe_button_box > .o_dropdown_more {
width: 14.28571429%;
}
}
@media (min-width: 1200px) {
.o_form_view .oe_button_box > .btn.oe_stat_button, .o_form_view .oe_button_box > .o_dropdown_more {
width: 12.5%;
}
}
.o_form_view .oe_button_box .btn.oe_stat_button {
color: #4c4c4c;
height: 44px;
padding: 0 6px 0 0 !important;
text-align: left;
white-space: nowrap;
background-color: transparent;
opacity: 0.8;
border-radius: 0px;
margin-bottom: 0;
}
.o_form_view .oe_button_box .btn.oe_stat_button:hover, .o_form_view .oe_button_box .btn.oe_stat_button:focus {
background-color: rgba(0, 0, 0, 0.03);
color: inherit;
opacity: 1;
}
.o_form_view .oe_button_box .btn.oe_stat_button > .o_button_icon {
margin-left: 6px;
display: inline-block;
vertical-align: middle;
line-height: 44px;
width: 30%;
}
.o_form_view .oe_button_box .btn.oe_stat_button > .o_button_icon:before {
font-size: 22px;
vertical-align: middle;
}
.o_form_view .oe_button_box .btn.oe_stat_button > .o_field_percent_pie {
margin-left: 6px;
}
.o_form_view .oe_button_box .btn.oe_stat_button > span {
display: block;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: top;
white-space: normal;
}
.o_form_view .oe_button_box .btn.oe_stat_button > .o_stat_info, .o_form_view .oe_button_box .btn.oe_stat_button > span {
display: inline-block;
vertical-align: middle;
font-weight: 500;
max-width: 70%;
padding-right: 6px;
line-height: 1.3;
}
.o_form_view .oe_button_box .btn.oe_stat_button > .o_stat_info > .o_stat_value, .o_form_view .oe_button_box .btn.oe_stat_button > .o_stat_info > .o_stat_text, .o_form_view .oe_button_box .btn.oe_stat_button > span > .o_stat_value, .o_form_view .oe_button_box .btn.oe_stat_button > span > .o_stat_text {
display: block;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: top;
}
.o_form_view .oe_button_box .btn.oe_stat_button > .o_stat_info .o_stat_value, .o_form_view .oe_button_box .btn.oe_stat_button > span .o_stat_value {
font-weight: 700;
color: #7C7BAD;
line-height: 1.2;
}
.o_form_view .oe_button_box .btn.oe_stat_button > .o_stat_info .o_stat_text, .o_form_view .oe_button_box .btn.oe_stat_button > span .o_stat_text {
line-height: 1.2;
}
.o_form_view .oe_button_box .btn.oe_stat_button:not(:hover) .o_stat_info > .o_hover {
display: none !important;
}
.o_form_view .oe_button_box .btn.oe_stat_button:hover .o_stat_info > .o_not_hover {
display: none !important;
}
.o_form_view .oe_button_box .btn.oe_stat_button.o_button_more {
text-align: center;
}
.o_form_view .oe_button_box .btn.oe_stat_button.o_button_more:after {
margin-left: 5px;
content: "";
display: inline-block;
width: 0;
height: 0;
vertical-align: middle;
border-bottom: 0;
border-left: 0.3em solid transparent;
border-right: 0.3em solid transparent;
border-top: 0.3em solid;
-moz-transform: scale(0.9999);
}
.o_form_view .oe_button_box .btn.oe_stat_button.o_button_more[aria-expanded="true"]:after {
margin-left: 5px;
content: "";
display: inline-block;
width: 0;
height: 0;
vertical-align: middle;
border-bottom: 0.3em solid;
border-left: 0.3em solid transparent;
border-right: 0.3em solid transparent;
border-top: 0;
-moz-transform: scale(0.9999);
}
.o_form_view .oe_button_box > .o_dropdown_more {
position: absolute;
top: 100%;
left: auto;
bottom: auto;
right: 0;
min-width: 0;
border: none;
border: 1px solid #dee2e6;
margin: 0;
padding: 0;
}
@media (max-width: 767.98px) {
.o_form_view .oe_button_box > .o_dropdown_more {
position: relative !important;
transform: none !important;
will-change: inherit !important;
margin-bottom: 20px;
width: 100%;
border-width: 0px;
}
}
.o_form_view .oe_button_box > .o_dropdown_more > .btn.oe_stat_button {
width: 100%;
border: none;
border-bottom: 1px solid #dee2e6;
}
@media (max-width: 767.98px) {
.o_form_view .oe_button_box > .o_dropdown_more > .btn.oe_stat_button {
display: inline-block;
width: 33.33333333%;
}
}
@media all and (-ms-high-contrast: none) {
.o_form_view .oe_button_box .btn.oe_stat_button.dropdown-item {
height: 44px !important;
padding: 5px 0 5px 0 !important;
border-left: none !important;
}
.o_form_view .oe_button_box .btn.oe_stat_button.dropdown-item > .o_button_icon {
line-height: normal;
}
}
@supports (display: -ms-grid) {
.o_form_view .oe_button_box .btn.oe_stat_button.dropdown-item {
height: 44px !important;
padding: 5px 0 5px 0 !important;
border-left: none !important;
}
.o_form_view .oe_button_box .btn.oe_stat_button.dropdown-item > .o_button_icon {
line-height: normal;
}
}
.o_form_view .oe_title > h1, .o_form_view .oe_title > h2, .o_form_view .oe_title > h3 {
width: 100%;
margin-top: 0;
margin-bottom: 0;
line-height: inherit;
}
.o_form_view .oe_title > h1.d-flex > .o_input, .o_form_view .oe_title > h2.d-flex > .o_input, .o_form_view .oe_title > h3.d-flex > .o_input {
height: max-content;
}
.o_form_view .oe_title .o_priority > .o_priority_star {
font-size: inherit;
}
.o_form_view .oe_avatar {
float: right;
margin-bottom: 10px;
}
.o_form_view .oe_avatar > img {
max-width: 90px;
max-height: 90px;
vertical-align: top;
border: 1px solid #a8a8a8;
}
.o_form_view .o_group {
display: inline-block;
width: 100%;
margin: 10px 0;
}
.o_form_view .o_group .o_group_col_1 {
display: inline-block;
width: 8%;
vertical-align: top;
}
.o_form_view .o_group .o_group_col_2 {
display: inline-block;
width: 16%;
vertical-align: top;
}
.o_form_view .o_group .o_group_col_3 {
display: inline-block;
width: 25%;
vertical-align: top;
}
.o_form_view .o_group .o_group_col_4 {
display: inline-block;
width: 33%;
vertical-align: top;
}
.o_form_view .o_group .o_group_col_5 {
display: inline-block;
width: 41%;
vertical-align: top;
}
.o_form_view .o_group .o_group_col_6 {
display: inline-block;
width: 50%;
vertical-align: top;
}
.o_form_view .o_group .o_group_col_7 {
display: inline-block;
width: 58%;
vertical-align: top;
}
.o_form_view .o_group .o_group_col_8 {
display: inline-block;
width: 66%;
vertical-align: top;
}
.o_form_view .o_group .o_group_col_9 {
display: inline-block;
width: 75%;
vertical-align: top;
}
.o_form_view .o_group .o_group_col_10 {
display: inline-block;
width: 83%;
vertical-align: top;
}
.o_form_view .o_group .o_group_col_11 {
display: inline-block;
width: 91%;
vertical-align: top;
}
.o_form_view .o_group .o_group_col_12 {
display: inline-block;
width: 100%;
vertical-align: top;
}
.o_form_view .o_group.o_inner_group {
display: inline-table;
}
.o_form_view .o_group.o_inner_group > tbody > tr > td {
vertical-align: top;
}
.o_form_view .o_group.o_inner_group > tbody > tr > td.o_td_label {
width: 0%;
padding: 0 15px 0 0;
min-width: 150px;
}
.o_form_view .o_group.o_inner_group > tbody > tr > td span.o_field_widget, .o_form_view .o_group.o_inner_group > tbody > tr > td .o_field_boolean.o_field_widget, .o_form_view .o_group.o_inner_group > tbody > tr > td .oe_avatar.o_field_widget, .o_form_view .o_group.o_inner_group > tbody > tr > td .o_form_uri.o_field_widget {
width: auto;
}
.o_form_view .o_group .o_form_label {
font-weight: normal;
}
.o_form_view .o_group .o_field_widget {
width: 100%;
}
.o_form_view .o_group .o_field_widget > .btn {
-webkit-box-flex: 0;
-webkit-flex: 0 0 auto;
flex: 0 0 auto;
padding: 0 10px;
}
.o_form_view .o_group :not(.o_row):not(.o_data_cell) > .o_field_widget > .o_input_dropdown, .o_form_view .o_group .o_row > .o_field_widget:last-child > .o_input_dropdown {
-webkit-box-flex: 1;
-webkit-flex: 1 0 auto;
flex: 1 0 auto;
}
.o_form_view .o_group.o_label_nowrap .o_form_label {
white-space: nowrap;
}
.o_form_view .o_group .o_td_label .o_form_label {
font-weight: bold;
margin-right: 0px;
}
.o_form_view .o_horizontal_separator {
font-size: 1.625rem;
margin: 5px 0;
}
.o_form_view .o_horizontal_separator:empty {
height: 10px;
}
.o_form_view .o_notebook {
clear: both;
margin-top: 10px;
}
.o_form_view .o_notebook .tab-content > .tab-pane {
padding: 16px 0;
}
.o_form_view .o_form_label {
margin: 0 5px 0 0;
font-size: 1.08333333rem;
line-height: 1.5;
font-weight: bold;
}
.o_form_view .o_field_widget {
margin-bottom: 5px;
}
.o_form_view .o_field_widget .o_field_widget, .o_form_view .btn .o_field_widget {
margin-bottom: 0px;
}
.o_form_view span.o_field_translate {
padding: 0 5px 0 0 !important;
vertical-align: top;
position: relative;
margin-left: -35px;
width: 35px !important;
display: inline-block;
text-align: right;
border: none;
}
.o_form_view input.o_field_translate, .o_form_view textarea.o_field_translate {
padding-right: 25px;
}
.o_form_view iframe.wysiwyg_iframe + .o_field_translate {
right: 30px !important;
top: 7px !important;
}
.o_form_view .o_field_text.oe_inline, .o_form_view .o_field_text.oe_left, .o_form_view .o_field_text.oe_right, .o_form_view .o_field_text.o_group.o_inner_group.oe_subtotal_footer {
width: 100% !important;
}
@media (min-width: 475px) {
.o_form_view .o_field_text.oe_inline, .o_form_view .o_field_text.oe_left, .o_form_view .o_field_text.oe_right, .o_form_view .o_field_text.o_group.o_inner_group.oe_subtotal_footer {
width: 45% !important;
}
}
.o_form_view .o_field_widget.o_field_one2many, .o_form_view .o_field_widget.o_field_many2many {
width: 100%;
}
.o_form_view .o_field_widget.o_field_one2many > div, .o_form_view .o_field_widget.o_field_many2many > div {
width: 100%;
}
.o_form_view .o_group.o_inner_group.oe_subtotal_footer > tbody > tr > td {
padding: 0;
}
.o_form_view .o_group.o_inner_group.oe_subtotal_footer > tbody > tr > td.o_td_label {
text-align: right;
}
.o_form_view .o_group.o_inner_group.oe_subtotal_footer > tbody > tr > td .o_form_label {
padding-right: 20px;
min-width: 0;
white-space: nowrap;
}
.o_form_view .o_group.o_inner_group.oe_subtotal_footer > tbody > tr > td .o_form_label:after {
content: ":";
}
.o_form_view .o_group.o_inner_group.oe_subtotal_footer > tbody > tr > td .o_field_widget {
text-align: right;
-webkit-box-pack: end;
justify-content: flex-end;
width: 100%;
}
.o_form_view .o_group.o_inner_group.oe_subtotal_footer > tbody > tr:first-child > td {
padding-top: 4px;
}
.o_form_view .o_group.o_inner_group.oe_subtotal_footer .oe_subtotal_footer_separator {
width: 100%;
text-align: right;
border-top: 1px solid #dee2e6;
font-weight: bold;
font-size: 1.3em;
}
.o_form_view .o_address_format {
width: 100%;
}
.o_form_view .o_address_format .o_address_street, .o_form_view .o_address_format .o_address_country {
display: -webkit-box;
display: -webkit-flex;
display: flex;
}
.o_form_view .o_address_format .o_address_city {
margin-right: 2%;
}
.o_form_view .o_address_format .o_address_state {
margin-right: 2%;
}
.o_form_view .o_address_format.o_zip_city .o_address_zip {
margin-right: 2%;
}
.o_form_view .o_address_format.o_zip_city .o_address_city {
margin-right: 0;
}
.o_form_view .o_address_format.o_zip_city .o_address_state {
display: block;
margin-right: 0;
}
.o_form_view .o_address_format.o_city_state .o_address_state {
margin-right: 0;
}
.o_form_view .o_address_format.o_city_state .o_address_zip {
display: block;
margin-right: 0;
}
.o_form_view .o_address_format > span.o_field_widget {
width: auto;
}
.o_form_view.o_form_editable .o_address_format .o_address_city {
width: 48%;
}
.o_form_view.o_form_editable .o_address_format div.o_address_state {
width: 48%;
}
.o_form_view.o_form_editable .o_address_format input.o_address_zip {
width: 25%;
}
.o_form_view.o_form_editable .o_address_format.o_zip_city .o_address_zip {
width: 38%;
}
.o_form_view.o_form_editable .o_address_format.o_zip_city .o_address_city {
width: 60%;
}
.o_form_view.o_form_editable .o_address_format.o_zip_city .o_address_state {
width: 100%;
}
.o_form_view.o_form_editable .o_address_format.o_city_state .o_address_city {
width: 50%;
}
.o_form_view.o_form_editable .o_address_format.o_city_state .o_address_state {
width: 48%;
}
.o_form_view.o_form_editable .o_address_format.o_city_state .o_address_zip {
width: 100%;
}
.o_form_view .o_field_boolean {
margin-right: 5px;
}
.o_form_view .o_tz_warning {
color: #dc3545;
cursor: help;
position: absolute;
margin-left: 10px;
margin-top: 5px;
}
.o_form_view .o_field_widget .o_kanban_view.o_kanban_ungrouped {
padding: 0;
}
.o_form_view .o_field_widget .o_kanban_view.o_kanban_ungrouped .o_kanban_record {
box-shadow: none;
}
.o_form_view .o_field_widget .o_list_view {
margin-bottom: 10px;
}
.o_form_view .o_field_widget .o_list_view > tfoot > tr > td {
padding: 3px;
color: #4c4c4c;
}
.o_form_view.o_form_readonly .o_field_widget .o_list_view .o_row_handle {
display: none;
}
.o_form_view .o_field_widget.o_readonly_modifier .o_list_view .o_row_handle {
display: none;
}
.o_form_view.oe_form_configuration .o_group .o_form_label {
white-space: nowrap;
}
.o_form_view.oe_form_configuration h2 {
margin-top: 32px !important;
}
.o_form_view.o_company_document_layout .report_layout_container {
display: inline-block;
}
.o_form_view.o_company_document_layout .report_layout_container div {
display: inline-block;
}
.o_form_view.o_company_document_layout .report_layout_container div img {
margin-left: 0 !important;
}
.o_form_view.o_company_document_layout img[name="logo"] {
max-height: 100px;
max-width: 300px;
}
.modal .modal-dialog .o_form_view .o_statusbar_buttons > .btn {
margin-top: 2px;
margin-bottom: 2px;
}
.modal .modal-dialog .o_form_view .o_form_sheet_bg {
padding: 0;
}
.modal .modal-dialog .o_form_view .o_form_sheet_bg > .o_form_statusbar, .modal .modal-dialog .o_form_view .o_form_sheet_bg > .alert {
margin-left: 0;
margin-right: 0;
}
.modal .modal-dialog .o_form_view .o_form_sheet_bg > .o_form_sheet {
box-shadow: none;
width: 100%;
margin: 0 auto;
max-width: none;
border: none;
}
.modal .modal-dialog:not(.modal-lg) .o_form_view .o_group {
width: 100%;
}
.modal .modal-dialog .o_onboarding_payment_acquirer_wizard a[type="action"] {
color: #7C7BAD;
cursor: pointer;
}
@media print {
.oe_button_box, .o_form_statusbar {
display: none !important;
}
}
.o_control_panel .o_form_buttons_view > button:first-child {
float: left;
margin-right: 4px;
}
.o_form_view.o_xxs_form_view .oe_title {
word-break: break-all;
}
.o_form_view.o_xxs_form_view .o_group.o_inner_group {
display: block;
margin-bottom: 20px;
}
.o_form_view.o_xxs_form_view .o_group.o_inner_group > tbody {
display: block;
}
.o_form_view.o_xxs_form_view .o_group.o_inner_group > tbody > tr {
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
}
.o_form_view.o_xxs_form_view .o_group.o_inner_group > tbody > tr > td {
-webkit-box-flex: 1;
-webkit-flex: 1 0 auto;
flex: 1 0 auto;
display: block;
max-width: 100%;
padding: 0;
width: auto !important;
}
.o_form_view.o_xxs_form_view .o_group.o_inner_group > tbody > tr > td.o_td_label {
width: 94% !important;
line-height: 0.8;
}
.o_form_view.o_xxs_form_view .o_group.o_inner_group > tbody > tr > td .o_field_widget {
margin-bottom: 10px;
}
.o_form_view.o_xxs_form_view .o_group.o_inner_group > tbody > tr > td .o_field_widget > .o_field_widget {
margin-bottom: 0;
}
.o_form_view.o_xxs_form_view .o_group.o_inner_group > tbody > tr > td .o_field_widget.o_field_boolean {
margin-right: 0;
}
.o_form_view.o_xxs_form_view .o_group.o_inner_group > tbody > tr > td .o_input_dropdown {
width: auto;
max-width: 100%;
}
.o_settings_container {
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-box-flex: 0;
-webkit-flex: 0 1 auto;
flex: 0 1 auto;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
}
.o_settings_container .o_form_label.o_light_label, .o_settings_container .o_light_label .o_form_label {
font-weight: normal;
}
.o_settings_container .o_setting_box:visible:nth-child(odd) {
clear: left;
}
.o_settings_container .text-muted {
color: #aaaaaa;
}
.o_settings_container .o_setting_box {
margin-bottom: 8px;
margin-top: 8px;
}
.o_settings_container .o_setting_box .o_setting_left_pane {
width: 24px;
float: left;
}
.o_settings_container .o_setting_box .o_setting_left_pane .o_enterprise_label {
position: absolute;
top: 0px;
right: 40px;
}
.o_settings_container .o_setting_box .o_setting_right_pane {
margin-left: 30px;
border-left: 1px solid #bbbbbb;
padding-left: 10px;
}
.o_settings_container .o_setting_box .o_setting_right_pane .o_input_dropdown > .o_input {
width: 100%;
}
.o_settings_container .o_setting_box .o_setting_right_pane .o_field_widget {
width: 50%;
-webkit-box-flex: 0;
-webkit-flex: 0 0 auto;
flex: 0 0 auto;
}
.o_settings_container .o_setting_box .o_setting_right_pane .o_field_widget.o_field_many2manytags > .o_field_widget {
flex: 1 0 50px;
}
.o_settings_container .o_setting_box .o_setting_right_pane button.btn-link:first-child {
padding: 0;
}
.o_settings_container .o_setting_box .o_setting_right_pane a.oe-link {
font-size: 12px;
}
odoo.define('account.payment', function (require) {
"use strict";
var AbstractField = require('web.AbstractField');
var core = require('web.core');
var field_registry = require('web.field_registry');
var field_utils = require('web.field_utils');
var QWeb = core.qweb;
var _t = core._t;
var ShowPaymentLineWidget = AbstractField.extend({
events: _.extend({
'click .outstanding_credit_assign': '_onOutstandingCreditAssign',
}, AbstractField.prototype.events),
supportedFieldTypes: ['char'],
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
/**
* @override
* @returns {boolean}
*/
isSet: function () {
return true;
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* @private
* @override
*/
_render: function () {
var self = this;
var info = JSON.parse(this.value);
if (!info) {
this.$el.html('');
return;
}
_.each(info.content, function (k, v) {
k.index = v;
k.amount = field_utils.format.float(k.amount, {digits: k.digits});
if (k.date) {
k.date = field_utils.format.date(field_utils.parse.date(k.date, {}, {isUTC: true}));
}
});
this.$el.html(QWeb.render('ShowPaymentInfo', {
lines: info.content,
outstanding: info.outstanding,
title: info.title
}));
_.each(this.$('.js_payment_info'), function (k, v) {
var isRTL = _t.database.parameters.direction === "rtl";
var content = info.content[v];
var options = {
content: function () {
var $content = $(QWeb.render('PaymentPopOver', content));
var unreconcile_button = $content.filter('.js_unreconcile_payment').on('click', self._onRemoveMoveReconcile.bind(self));
$content.filter('.js_open_payment').on('click', self._onOpenPayment.bind(self));
return $content;
},
html: true,
placement: isRTL ? 'bottom' : 'left',
title: 'Payment Information',
trigger: 'focus',
delay: {"show": 0, "hide": 100},
container: $(k).parent(), // FIXME Ugly, should use the default body container but system & tests to adapt to properly destroy the popover
};
$(k).popover(options);
});
},
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* @private
* @override
* @param {MouseEvent} event
*/
_onOpenPayment: function (event) {
var paymentId = parseInt($(event.target).attr('payment-id'));
var moveId = parseInt($(event.target).attr('move-id'));
var res_model;
var id;
if (paymentId !== undefined && !isNaN(paymentId)) {
res_model = "account.payment";
id = paymentId;
} else if (moveId !== undefined && !isNaN(moveId)) {
res_model = "account.move";
id = moveId;
}
//Open form view of account.move with id = move_id
if (res_model && id) {
this.do_action({
type: 'ir.actions.act_window',
res_model: res_model,
res_id: id,
views: [[false, 'form']],
target: 'current'
});
}
},
/**
* @private
* @override
* @param {MouseEvent} event
*/
_onOutstandingCreditAssign: function (event) {
event.stopPropagation();
event.preventDefault();
var self = this;
var id = $(event.target).data('id') || false;
this._rpc({
model: 'account.move',
method: 'js_assign_outstanding_line',
args: [JSON.parse(this.value).move_id, id],
}).then(function () {
self.trigger_up('reload');
});
},
/**
* @private
* @override
* @param {MouseEvent} event
*/
_onRemoveMoveReconcile: function (event) {
var self = this;
var moveId = parseInt($(event.target).attr('move-id'));
var partialId = parseInt($(event.target).attr('partial-id'));
if (partialId !== undefined && !isNaN(partialId)) {
this._rpc({
model: 'account.move',
method: 'js_remove_outstanding_partial',
args: [moveId, partialId],
}).then(function () {
self.trigger_up('reload');
});
}
},
});
field_registry.add('payment', ShowPaymentLineWidget);
return {
ShowPaymentLineWidget: ShowPaymentLineWidget
};
});
odoo.define('account.AccountPortalSidebar', function (require) {
'use strict';
const dom = require('web.dom');
var publicWidget = require('web.public.widget');
var PortalSidebar = require('portal.PortalSidebar');
var utils = require('web.utils');
publicWidget.registry.AccountPortalSidebar = PortalSidebar.extend({
selector: '.o_portal_invoice_sidebar',
events: {
'click .o_portal_invoice_print': '_onPrintInvoice',
},
/**
* @override
*/
start: function () {
var def = this._super.apply(this, arguments);
var $invoiceHtml = this.$el.find('iframe#invoice_html');
var updateIframeSize = this._updateIframeSize.bind(this, $invoiceHtml);
$(window).on('resize', updateIframeSize);
var iframeDoc = $invoiceHtml[0].contentDocument || $invoiceHtml[0].contentWindow.document;
if (iframeDoc.readyState === 'complete') {
updateIframeSize();
} else {
$invoiceHtml.on('load', updateIframeSize);
}
return def;
},
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* Called when the iframe is loaded or the window is resized on customer portal.
* The goal is to expand the iframe height to display the full report without scrollbar.
*
* @private
* @param {object} $el: the iframe
*/
_updateIframeSize: function ($el) {
var $wrapwrap = $el.contents().find('div#wrapwrap');
// Set it to 0 first to handle the case where scrollHeight is too big for its content.
$el.height(0);
$el.height($wrapwrap[0].scrollHeight);
// scroll to the right place after iframe resize
if (!utils.isValidAnchor(window.location.hash)) {
return;
}
var $target = $(window.location.hash);
if (!$target.length) {
return;
}
dom.scrollTo($target[0], {duration: 0});
},
/**
* @private
* @param {MouseEvent} ev
*/
_onPrintInvoice: function (ev) {
ev.preventDefault();
var href = $(ev.currentTarget).attr('href');
this._printIframeContent(href);
},
});
});
odoo.define('account.ShowResequenceRenderer', function (require) {
"use strict";
const {Component} = owl;
const {useState} = owl.hooks;
const AbstractFieldOwl = require('web.AbstractFieldOwl');
const field_registry = require('web.field_registry_owl');
class ChangeLine extends Component {
}
ChangeLine.template = 'account.ResequenceChangeLine';
ChangeLine.props = ["changeLine", 'ordering'];
class ShowResequenceRenderer extends AbstractFieldOwl {
constructor(...args) {
super(...args);
this.data = this.value ? JSON.parse(this.value) : {
changeLines: [],
ordering: 'date',
};
}
async willUpdateProps(nextProps) {
await super.willUpdateProps(nextProps);
Object.assign(this.data, JSON.parse(this.value));
}
}
ShowResequenceRenderer.template = 'account.ResequenceRenderer';
ShowResequenceRenderer.components = {ChangeLine}
field_registry.add('account_resequence_widget', ShowResequenceRenderer);
return ShowResequenceRenderer;
});
odoo.define('account.hierarchy.selection', function (require) {
"use strict";
var core = require('web.core');
var relational_fields = require('web.relational_fields');
var _t = core._t;
var registry = require('web.field_registry');
var FieldSelection = relational_fields.FieldSelection;
var qweb = core.qweb;
var HierarchySelection = FieldSelection.extend({
_renderEdit: function () {
var self = this;
var prom = Promise.resolve()
if (!self.hierarchy_groups) {
prom = this._rpc({
model: 'account.account.type',
method: 'search_read',
kwargs: {
domain: [],
fields: ['id', 'internal_group', 'display_name'],
},
}).then(function (arg) {
self.values = _.map(arg, v => [v['id'], v['display_name']])
self.hierarchy_groups = [
{
'name': _t('Balance Sheet'),
'children': [
{
'name': _t('Assets'),
'ids': _.map(_.filter(arg, v => v['internal_group'] == 'asset'), v => v['id'])
},
{
'name': _t('Liabilities'),
'ids': _.map(_.filter(arg, v => v['internal_group'] == 'liability'), v => v['id'])
},
{
'name': _t('Equity'),
'ids': _.map(_.filter(arg, v => v['internal_group'] == 'equity'), v => v['id'])
},
],
},
{
'name': _t('Profit & Loss'),
'children': [
{
'name': _t('Income'),
'ids': _.map(_.filter(arg, v => v['internal_group'] == 'income'), v => v['id'])
},
{
'name': _t('Expense'),
'ids': _.map(_.filter(arg, v => v['internal_group'] == 'expense'), v => v['id'])
},
],
},
{
'name': _t('Other'),
'ids': _.map(_.filter(arg, v => !['asset', 'liability', 'equity', 'income', 'expense'].includes(v['internal_group'])), v => v['id'])
},
]
});
}
Promise.resolve(prom).then(function () {
self.$el.empty();
self._addHierarchy(self.$el, self.hierarchy_groups, 0);
var value = self.value;
if (self.field.type === 'many2one' && value) {
value = value.data.id;
}
self.$el.val(JSON.stringify(value));
});
},
_addHierarchy: function (el, group, level) {
var self = this;
_.each(group, function (item) {
var optgroup = $('<optgroup/>').attr(({
'label': $('<div/>').html('&nbsp;'.repeat(6 * level) + item['name']).text(),
}))
_.each(item['ids'], function (id) {
var value = _.find(self.values, v => v[0] == id)
optgroup.append($('<option/>', {
value: JSON.stringify(value[0]),
text: value[1],
}));
})
el.append(optgroup)
if (item['children']) {
self._addHierarchy(el, item['children'], level + 1);
}
})
}
});
registry.add("account_hierarchy_selection", HierarchySelection);
});
odoo.define('account.bank_statement', function (require) {
"use strict";
var KanbanController = require("web.KanbanController");
var ListController = require("web.ListController");
var includeDict = {
renderButtons: function () {
this._super.apply(this, arguments);
if (this.modelName === "account.bank.statement") {
var data = this.model.get(this.handle);
if (data.context.journal_type !== 'cash') {
this.$buttons.find('button.o_button_import').hide();
}
}
}
};
KanbanController.include(includeDict);
ListController.include(includeDict);
});
\ No newline at end of file
odoo.define('account.upload.bill.mixin', function (require) {
"use strict";
var core = require('web.core');
var _t = core._t;
var qweb = core.qweb;
var UploadBillMixin = {
start: function () {
// define a unique uploadId and a callback method
this.fileUploadID = _.uniqueId('account_bill_file_upload');
$(window).on(this.fileUploadID, this._onFileUploaded.bind(this));
return this._super.apply(this, arguments);
},
_onAddAttachment: function (ev) {
// Auto submit form once we've selected an attachment
var $input = $(ev.currentTarget).find('input.o_input_file');
if ($input.val() !== '') {
var $binaryForm = this.$('.o_vendor_bill_upload form.o_form_binary_form');
$binaryForm.submit();
}
},
_onFileUploaded: function () {
// Callback once attachment have been created, create a bill with attachment ids
var self = this;
var attachments = Array.prototype.slice.call(arguments, 1);
// Get id from result
var attachent_ids = attachments.reduce(function (filtered, record) {
if (record.id) {
filtered.push(record.id);
}
return filtered;
}, []);
return this._rpc({
model: 'account.journal',
method: 'create_invoice_from_attachment',
args: ["", attachent_ids],
context: this.initialState.context,
}).then(function (result) {
self.do_action(result);
});
},
_onUpload: function (event) {
var self = this;
// If hidden upload form don't exists, create it
var $formContainer = this.$('.o_content').find('.o_vendor_bill_upload');
if (!$formContainer.length) {
$formContainer = $(qweb.render('account.BillsHiddenUploadForm', {widget: this}));
$formContainer.appendTo(this.$('.o_content'));
}
// Trigger the input to select a file
this.$('.o_vendor_bill_upload .o_input_file').click();
},
}
return UploadBillMixin;
});
odoo.define('account.bills.tree', function (require) {
"use strict";
var core = require('web.core');
var ListController = require('web.ListController');
var ListView = require('web.ListView');
var UploadBillMixin = require('account.upload.bill.mixin');
var viewRegistry = require('web.view_registry');
var BillsListController = ListController.extend(UploadBillMixin, {
buttons_template: 'BillsListView.buttons',
events: _.extend({}, ListController.prototype.events, {
'click .o_button_upload_bill': '_onUpload',
'change .o_vendor_bill_upload .o_form_binary_form': '_onAddAttachment',
}),
});
var BillsListView = ListView.extend({
config: _.extend({}, ListView.prototype.config, {
Controller: BillsListController,
}),
});
viewRegistry.add('account_tree', BillsListView);
});
odoo.define('account.dashboard.kanban', function (require) {
"use strict";
var core = require('web.core');
var KanbanController = require('web.KanbanController');
var KanbanView = require('web.KanbanView');
var UploadBillMixin = require('account.upload.bill.mixin');
var viewRegistry = require('web.view_registry');
var DashboardKanbanController = KanbanController.extend(UploadBillMixin, {
events: _.extend({}, KanbanController.prototype.events, {
'click .o_button_upload_bill': '_onUpload',
'change .o_vendor_bill_upload .o_form_binary_form': '_onAddAttachment',
}),
/**
* We override _onUpload (from the upload bill mixin) to pass default_journal_id
* and default_move_type in context.
*
* @override
*/
_onUpload: function (event) {
var kanbanRecord = $(event.currentTarget).closest('.o_kanban_record').data('record');
this.initialState.context['default_journal_id'] = kanbanRecord.id;
if ($(event.currentTarget).attr('journal_type') == 'sale') {
this.initialState.context['default_move_type'] = 'out_invoice'
} else if ($(event.currentTarget).attr('journal_type') == 'purchase') {
this.initialState.context['default_move_type'] = 'in_invoice'
}
UploadBillMixin._onUpload.apply(this, arguments);
}
});
var DashboardKanbanView = KanbanView.extend({
config: _.extend({}, KanbanView.prototype.config, {
Controller: DashboardKanbanController,
}),
});
viewRegistry.add('account_dashboard_kanban', DashboardKanbanView);
});
odoo.define('account.ShowGroupedList', function (require) {
"use strict";
const {Component} = owl;
const {useState} = owl.hooks;
const AbstractFieldOwl = require('web.AbstractFieldOwl');
const field_registry = require('web.field_registry_owl');
class ListItem extends Component {
}
ListItem.template = 'account.GroupedItemTemplate';
ListItem.props = ["item_vals", "options"];
class ListGroup extends Component {
}
ListGroup.template = 'account.GroupedItemsTemplate';
ListGroup.components = {ListItem}
ListGroup.props = ["group_vals", "options"];
class ShowGroupedList extends AbstractFieldOwl {
constructor(...args) {
super(...args);
this.data = this.value ? JSON.parse(this.value) : {
groups_vals: [],
options: {
discarded_number: '',
columns: [],
},
};
}
async willUpdateProps(nextProps) {
await super.willUpdateProps(nextProps);
Object.assign(this.data, JSON.parse(this.value));
}
}
ShowGroupedList.template = 'account.GroupedListTemplate';
ShowGroupedList.components = {ListGroup}
field_registry.add('grouped_view_widget', ShowGroupedList);
return ShowGroupedList;
});
odoo.define('account.activity', function (require) {
"use strict";
var AbstractField = require('web.AbstractField');
var core = require('web.core');
var field_registry = require('web.field_registry');
var QWeb = core.qweb;
var _t = core._t;
var VatActivity = AbstractField.extend({
className: 'o_journal_activity_kanban',
events: {
'click .see_all_activities': '_onOpenAll',
'click .see_activity': '_onOpenActivity',
},
init: function () {
this.MAX_ACTIVITY_DISPLAY = 5;
this._super.apply(this, arguments);
},
//------------------------------------------------------------
// Private
//------------------------------------------------------------
_render: function () {
var self = this;
var info = JSON.parse(this.value);
if (!info) {
this.$el.html('');
return;
}
info.more_activities = false;
if (info.activities.length > this.MAX_ACTIVITY_DISPLAY) {
info.more_activities = true;
info.activities = info.activities.slice(0, this.MAX_ACTIVITY_DISPLAY);
}
this.$el.html(QWeb.render('accountJournalDashboardActivity', info));
},
_onOpenActivity: function (e) {
e.preventDefault();
var self = this;
self.do_action({
type: 'ir.actions.act_window',
name: _t('Journal Entry'),
target: 'current',
res_id: $(e.target).data('resId'),
res_model: 'account.move',
views: [[false, 'form']],
});
},
_onOpenAll: function (e) {
e.preventDefault();
var self = this;
self.do_action({
type: 'ir.actions.act_window',
name: _t('Journal Entries'),
res_model: 'account.move',
views: [[false, 'kanban'], [false, 'form']],
search_view_id: [false],
domain: [['journal_id', '=', self.res_id], ['activity_ids', '!=', false]],
});
}
})
field_registry.add('kanban_vat_activity', VatActivity);
return VatActivity;
});
odoo.define('account.section_and_note_backend', function (require) {
// The goal of this file is to contain JS hacks related to allowing
// section and note on sale order and invoice.
// [UPDATED] now also allows configuring products on sale order.
"use strict";
var FieldChar = require('web.basic_fields').FieldChar;
var FieldOne2Many = require('web.relational_fields').FieldOne2Many;
var fieldRegistry = require('web.field_registry');
var ListFieldText = require('web.basic_fields').ListFieldText;
var ListRenderer = require('web.ListRenderer');
var SectionAndNoteListRenderer = ListRenderer.extend({
/**
* We want section and note to take the whole line (except handle and trash)
* to look better and to hide the unnecessary fields.
*
* @override
*/
_renderBodyCell: function (record, node, index, options) {
var $cell = this._super.apply(this, arguments);
var isSection = record.data.display_type === 'line_section';
var isNote = record.data.display_type === 'line_note';
if (isSection || isNote) {
if (node.attrs.widget === "handle") {
return $cell;
} else if (node.attrs.name === "name") {
var nbrColumns = this._getNumberOfCols();
if (this.handleField) {
nbrColumns--;
}
if (this.addTrashIcon) {
nbrColumns--;
}
$cell.attr('colspan', nbrColumns);
} else {
$cell.removeClass('o_invisible_modifier');
return $cell.addClass('o_hidden');
}
}
return $cell;
},
/**
* We add the o_is_{display_type} class to allow custom behaviour both in JS and CSS.
*
* @override
*/
_renderRow: function (record, index) {
var $row = this._super.apply(this, arguments);
if (record.data.display_type) {
$row.addClass('o_is_' + record.data.display_type);
}
return $row;
},
/**
* We want to add .o_section_and_note_list_view on the table to have stronger CSS.
*
* @override
* @private
*/
_renderView: function () {
var self = this;
return this._super.apply(this, arguments).then(function () {
self.$('.o_list_table').addClass('o_section_and_note_list_view');
});
}
});
// We create a custom widget because this is the cleanest way to do it:
// to be sure this custom code will only impact selected fields having the widget
// and not applied to any other existing ListRenderer.
var SectionAndNoteFieldOne2Many = FieldOne2Many.extend({
/**
* We want to use our custom renderer for the list.
*
* @override
*/
_getRenderer: function () {
if (this.view.arch.tag === 'tree') {
return SectionAndNoteListRenderer;
}
return this._super.apply(this, arguments);
},
});
// This is a merge between a FieldText and a FieldChar.
// We want a FieldChar for section,
// and a FieldText for the rest (product and note).
var SectionAndNoteFieldText = function (parent, name, record, options) {
var isSection = record.data.display_type === 'line_section';
var Constructor = isSection ? FieldChar : ListFieldText;
return new Constructor(parent, name, record, options);
};
fieldRegistry.add('section_and_note_one2many', SectionAndNoteFieldOne2Many);
fieldRegistry.add('section_and_note_text', SectionAndNoteFieldText);
return SectionAndNoteListRenderer;
});
odoo.define('account.tax_group', function (require) {
"use strict";
var core = require('web.core');
var session = require('web.session');
var fieldRegistry = require('web.field_registry');
var AbstractField = require('web.AbstractField');
var fieldUtils = require('web.field_utils');
var QWeb = core.qweb;
var TaxGroupCustomField = AbstractField.extend({
events: {
'click .tax_group_edit': '_onClick',
'keydown .oe_tax_group_editable .tax_group_edit_input input': '_onKeydown',
'blur .oe_tax_group_editable .tax_group_edit_input input': '_onBlur',
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* This method is called by "_setTaxGroups". It is
* responsible for calculating taxes based on
* tax groups and triggering an event to
* notify the ORM of a change.
*
* @param {Id} taxGroupId
* @param {Float} deltaAmount
*/
_changeTaxValueByTaxGroup: function (taxGroupId, deltaAmount) {
const self = this;
// Search for the first tax line with the same tax group and modify its value
function applyChange(line_id) {
let debitAmount = 0;
let creditAmount = 0;
let amount_currency = 0;
if (line_id.data.currency_id) { // If multi currency enable
if (self.record.data.move_type === "in_invoice") {
amount_currency = line_id.data.amount_currency - deltaAmount;
} else {
amount_currency = line_id.data.amount_currency + deltaAmount;
}
} else {
let balance = line_id.data.price_subtotal;
balance -= deltaAmount;
if (self.record.data.move_type === "in_invoice") { // For vendor bill
if (balance > 0) {
debitAmount = balance;
} else if (balance < 0) {
creditAmount = -balance;
}
} else { // For refund
if (balance > 0) {
creditAmount = balance;
} else if (balance < 0) {
debitAmount = -balance;
}
}
}
// Trigger ORM
self.trigger_up('field_changed', {
dataPointID: self.record.id,
changes: {
line_ids: {
operation: "UPDATE",
id: line_id.id,
data: {amount_currency: amount_currency, debit: debitAmount, credit: creditAmount}
}
}, // account.move change
initialEvent: {
dataPointID: line_id.id,
changes: {amount_currency: amount_currency, debit: debitAmount, credit: creditAmount},
}, // account.move.line change
});
}
let line_id = self.record.data.line_ids.data.find(elem => elem.data.tax_group_id && elem.data.tax_group_id.data.id === taxGroupId);
if (line_id) {
applyChange(line_id);
} else {
const {limit, id, count} = self.record.data.line_ids;
let offset = count - limit;
self.trigger_up('load', {
id,
limit,
offset,
on_success: value => {
line_id = value.data.find(elem => elem.data.tax_group_id && elem.data.tax_group_id.data.id === taxGroupId);
applyChange(line_id);
},
});
}
},
/**
* This method checks that the document where the widget
* is located is of the "in_invoice" or "in_refund" type.
* This makes it possible to know if it is a purchase
* document.
*
* @returns boolean (true if the invoice is a purchase document)
*/
_isPurchaseDocument: function () {
return this.record.data.move_type === "in_invoice" || this.record.data.move_type === 'in_refund';
},
/**
* This method is part of the widget life cycle and allows you to render
* the widget.
*
* @private
* @override
*/
_render: function () {
var self = this;
// Display the pencil and allow the event to click and edit only on purchase that are not posted and in edit mode.
// since the field is readonly its mode will always be readonly. Therefore we have to use a trick by checking the
// formRenderer (the parent) and check if it is in edit in order to know the correct mode.
var displayEditWidget = self._isPurchaseDocument() && this.record.data.state === 'draft' && this.getParent().mode === 'edit';
this.$el.html($(QWeb.render('AccountTaxGroupTemplate', {
lines: self.value,
displayEditWidget: displayEditWidget,
})));
},
//--------------------------------------------------------------------------
// Handler
//--------------------------------------------------------------------------
/**
* This method is called when the user is in edit mode and
* leaves the <input> field. Then, we execute the code that
* modifies the information.
*
* @param {event} ev
*/
_onBlur: function (ev) {
ev.preventDefault();
var $input = $(ev.target);
var newValue = $input.val();
var currency = session.get_currency(this.record.data.currency_id.data.id);
try {
newValue = fieldUtils.parse.float(newValue); // Need a float for format the value.
newValue = fieldUtils.format.float(newValue, null, {digits: currency.digits}); // return a string rounded to currency precision
newValue = fieldUtils.parse.float(newValue); // convert back to Float to compare with oldValue to know if value has changed
} catch (err) {
$input.addClass('o_field_invalid');
return;
}
var oldValue = $input.data('originalValue');
if (newValue === oldValue || newValue === 0) {
return this._render();
}
var taxGroupId = $input.parents('.oe_tax_group_editable').data('taxGroupId');
this._changeTaxValueByTaxGroup(taxGroupId, oldValue - newValue);
},
/**
* This method is called when the user clicks on a specific <td>.
* it will hide the edit button and display the field to be edited.
*
* @param {event} ev
*/
_onClick: function (ev) {
ev.preventDefault();
var $taxGroupElement = $(ev.target).parents('.oe_tax_group_editable');
// Show input and hide previous element
$taxGroupElement.find('.tax_group_edit').addClass('d-none');
$taxGroupElement.find('.tax_group_edit_input').removeClass('d-none');
var $input = $taxGroupElement.find('.tax_group_edit_input input');
// Get original value and display it in user locale in the input
var formatedOriginalValue = fieldUtils.format.float($input.data('originalValue'), {}, {});
$input.focus(); // Focus the input
$input.val(formatedOriginalValue); //add value in user locale to the input
},
/**
* This method is called when the user is in edit mode and pressing
* a key on his keyboard. If this key corresponds to ENTER or TAB,
* the code that modifies the information is executed.
*
* @param {event} ev
*/
_onKeydown: function (ev) {
switch (ev.which) {
// Trigger only if the user clicks on ENTER or on TAB.
case $.ui.keyCode.ENTER:
case $.ui.keyCode.TAB:
// trigger blur to prevent the code being executed twice
$(ev.target).blur();
}
},
});
fieldRegistry.add('tax-group-custom-field', TaxGroupCustomField)
});
odoo.define('account.tour', function (require) {
"use strict";
var core = require('web.core');
var tour = require('web_tour.tour');
var _t = core._t;
tour.register('account_tour', {
url: "/web",
sequence: 60,
}, [
...tour.stepUtils.goToAppSteps('account.menu_finance', _t('Send invoices to your customers in no time with the <b>Invoicing app</b>.')),
{
trigger: "a.o_onboarding_step_action[data-method=action_open_base_onboarding_company]",
content: _t("Start by checking your company's data."),
position: "bottom",
}, {
trigger: "button[name=action_save_onboarding_company_step]",
extra_trigger: "a.o_onboarding_step_action[data-method=action_open_base_onboarding_company]",
content: _t("Looks good. Let's continue."),
position: "bottom",
}, {
trigger: "a.o_onboarding_step_action[data-method=action_open_base_document_layout]",
content: _t("Customize your layout."),
position: "bottom",
}, {
trigger: "button[name=document_layout_save]",
extra_trigger: "a.o_onboarding_step_action[data-method=action_open_base_document_layout]",
content: _t("Once everything is as you want it, validate."),
position: "top",
}, {
trigger: "a.o_onboarding_step_action[data-method=action_open_account_onboarding_create_invoice]",
content: _t("Now, we'll create your first invoice."),
position: "bottom",
}, {
trigger: "div[name=partner_id] input",
extra_trigger: "[name=move_type][raw-value=out_invoice]",
content: _t("Write a company name to <b>create one</b> or <b>see suggestions</b>."),
position: "bottom",
}, {
trigger: ".o_m2o_dropdown_option a:contains('Create')",
extra_trigger: "[name=move_type][raw-value=out_invoice]",
content: _t("Select first partner"),
auto: true,
}, {
trigger: ".modal-content button.btn-primary",
extra_trigger: "[name=move_type][raw-value=out_invoice]",
content: _t("Once everything is set, you are good to continue. You will be able to edit this later in the <b>Customers</b> menu."),
auto: true,
}, {
trigger: "div[name=invoice_line_ids] .o_field_x2many_list_row_add a:not([data-context])",
extra_trigger: "[name=move_type][raw-value=out_invoice]",
content: _t("Add a line to your invoice"),
}, {
trigger: "div[name=invoice_line_ids] textarea[name=name]",
extra_trigger: "[name=move_type][raw-value=out_invoice]",
content: _t("Fill in the details of the line."),
position: "bottom",
}, {
trigger: "div[name=invoice_line_ids] input[name=price_unit]",
extra_trigger: "[name=move_type][raw-value=out_invoice]",
content: _t("Set a price"),
position: "bottom",
run: 'text 100',
}, {
trigger: "button[name=action_post]",
extra_trigger: "[name=move_type][raw-value=out_invoice]",
content: _t("Once your invoice is ready, press CONFIRM."),
}, {
trigger: "button[name=action_invoice_sent]",
extra_trigger: "[name=move_type][raw-value=out_invoice]",
content: _t("Send the invoice and check what the customer will receive."),
}, {
trigger: "input[name=email]",
extra_trigger: "[name=move_type][raw-value=out_invoice]",
content: _t("Write here <b>your own email address</b> to test the flow."),
run: 'text customer@example.com',
auto: true,
}, {
trigger: ".modal-content button.btn-primary",
extra_trigger: "[name=move_type][raw-value=out_invoice]",
content: _t("Validate."),
auto: true,
}, {
trigger: "button[name=send_and_print_action]",
extra_trigger: "[name=move_type][raw-value=out_invoice]",
content: _t("Let's send the invoice."),
position: "top"
}
]);
});
.o_journal_activity_kanban {
display: block;
.align_activity_center {
width: 100%;
align-items: center;
margin-bottom: 5px;
}
}
\ No newline at end of file
.o_kanban_view.o_kanban_dashboard.o_account_kanban {
&.o_kanban_ungrouped .o_account_dashboard_header {
margin: (0 - $o-kanban-record-margin) ($o-kanban-record-margin - $o-horizontal-padding) $o-kanban-record-margin;
}
.o_account_dashboard_header {
flex: 1 0 100%;
flex-flow: column nowrap;
align-self: flex-start;
width: 100%;
height: auto; // cancel o_form_view height 100%, which hides the help tip message at the bottom of the screen
min-height: 0%; // cancel o_form_view min-height 100%, which hides the help tip message at the bottom of the screen
background-color: $o-view-background-color;
.o_form_statusbar {
padding-right: $o-horizontal-padding;
}
h4 {
font-size: $font-size-base;
font-weight: 500;
}
.fa-gift {
color: #eeeeee;
&:hover {
color: #555555;
}
}
.o_arrow_button.btn-secondary {
color: $text-muted;
text-transform: none;
font-weight: 500;
.o_account_dashboard_index {
color: gray('900');
}
&.o_action_done {
color: gray('900');
background-color: gray('200');
&:after {
border-left-color: gray('200');
}
.fa-check {
color: theme-color('success');
}
}
&:last-of-type {
margin-left: $o-horizontal-padding;
padding-left: $o-horizontal-padding*.5;
border-left: 1px solid gray('300');
}
}
}
}
.o_kanban_view.o_kanban_dashboard.o_account_kanban {
.o_kanban_record {
@include media-breakpoint-up(sm) {
.oe_kanban_action_button {
display: block;
margin-bottom: 5px;
}
}
.o_kanban_card_settings {
padding-top: $o-horizontal-padding/2;
padding-bottom: $o-horizontal-padding/2;
border-top: 1px solid;
border-color: $o-brand-lightsecondary;
}
.o_dashboard_star {
font-size: 12px;
&.fa-star-o {
color: $o-main-color-muted;
&:hover {
color: gold;
}
}
&.fa-star {
color: gold;
}
}
.o_dashboard_graph {
margin-bottom: -$o-horizontal-padding/2;
}
}
&.o_kanban_ungrouped {
.o_kanban_record {
width: 450px;
}
}
.o_kanban_group {
&:not(.o_column_folded) {
width: 450px + 2*$o-kanban-group-padding;
@include media-breakpoint-down(sm) {
width: 100%;
}
}
}
}
// Style for the widget "dashboard_graph"
.o_dashboard_graph {
position: relative;
margin: 16px -16px;
canvas {
height: 75px;
}
}
.o_sample_data .o_dashboard_graph.o_graph_linechart > svg g.nv-linesWrap g.nv-group.nv-series-0 {
fill: gray !important;
opacity: 0.1;
}
.progress-reconciliation {
.progress-bar {
font-size: 1.08333333rem;
height: 14px;
background-color: $o-enterprise-color;
span {
display: contents;
}
}
}
.o_reconciliation {
.o_filter_input_wrapper {
position: relative;
width: 150px;
margin: 0.5rem !important;
.searchIcon {
position: absolute;
right: 10px;
}
.o_filter_input {
border: none;
border-bottom: 1px black solid;
}
}
.import_to_suspense {
margin: 0.5rem !important;
}
.notification_area {
clear: both;
}
.o_view_noreconciliation {
max-width: none;
padding: 0 10%;
color: $o-main-color-muted;
font-size: 125%;
}
.accounting_view {
width: 100%;
.cell_left {
border-right: 1px solid #333;
padding-right: 5px;
}
.edit_amount {
margin-left: 20px;
color: #bbb;
}
.cell:hover .edit_amount {
color: #00A09D;
}
.strike_amount {
text-decoration: line-through;
}
tbody tr:hover .cell_account_code::before {
content: "\f068";
font-family: FontAwesome;
position: relative;
margin-left: -17px;
left: -4px;
line-height: 0;
padding: 3px 2px 5px 5px;
}
}
.o_multi_currency {
margin-right: 5px;
&.o_multi_currency_color_0 {
color: #dd6666;
}
&.o_multi_currency_color_1 {
color: #aaaaaa;
}
&.o_multi_currency_color_2 {
color: #66dd66;
}
&.o_multi_currency_color_3 {
color: #6666dd;
}
&.o_multi_currency_color_4 {
color: #dddd66;
}
&.o_multi_currency_color_5 {
color: #dd66dd;
}
&.o_multi_currency_color_6 {
color: #66dddd;
}
&.o_multi_currency_color_7 {
color: #aaa333;
}
}
.o_reconciliation_line {
margin-bottom: 30px;
table {
width: 100%;
vertical-align: top;
}
tbody tr {
cursor: pointer;
}
tr.already_reconciled {
color: $o-account-info-color;
}
tr.invalid {
text-decoration: line-through;
}
td {
padding: 1px 2px;
}
thead td {
border-top: $o-account-light-border;
padding-top: 4px;
padding-bottom: 5px;
background-color: $o-account-initial-line-background;
}
tfoot td {
color: #bbb;
}
/* columns */
.cell_action {
width: 15px;
color: gray('700');
background: #fff;
border: 0;
text-align: center;
.fa-add-remove:before {
content: "";
}
}
tr:hover .cell_action .fa-add-remove:before {
content: "\f068";
}
.is_tax .cell_action .fa-add-remove:before {
position: relative;
top: -18px;
}
.cell_account_code {
width: 80px;
padding-left: 5px;
}
.cell_due_date {
width: 100px;
}
.cell_label {
width: auto;
}
.cell_left {
padding-right: 5px;
}
.cell_right, .cell_left {
text-align: right;
width: 120px;
}
.cell_info_popover {
text-align: right;
width: 15px;
color: #ccc;
&:empty {
padding: 0;
width: 0;
}
}
table.accounting_view {
.cell_right, .cell_left, .cell_label, .cell_due_date, .cell_account_code, .cell_info_popover {
box-shadow: 0 1px 0 #EAEAEA;
}
}
/* info popover */
.popover {
max-width: none;
}
table.details {
vertical-align: top;
td:first-child {
vertical-align: top;
padding-right: 10px;
font-weight: bold;
}
}
tr.one_line_info {
td {
padding-top: 10px;
text-align: center;
color: $o-account-info-color;
}
}
/* Icons */
.toggle_match, .toggle_create {
transform: rotate(0deg);
transition: transform 300ms ease 0s;
}
.visible_toggle, &[data-mode="match"] .toggle_match, &[data-mode="create"] .toggle_create {
visibility: visible !important;
transform: rotate(90deg);
}
.toggle_create {
font-size: 10px;
}
/* Match view & Create view */
> .o_notebook {
display: none;
> .o_notebook_headers {
margin-right: 0;
margin-left: 0;
}
}
> .o_notebook > .tab-content > div {
border: 1px solid #ddd;
border-top: 0;
}
> .o_notebook .match table tr:hover {
background-color: #eee;
}
&:not([data-mode="inactive"]) > .o_notebook {
display: block;
}
&:not(:focus-within) .o_web_accesskey_overlay {
display: none;
}
&:focus caption .o_buttons button {
outline: none;
box-shadow: 4px 4px 4px 0px $o-enterprise-color;
}
&:focus {
outline: none;
box-shadow: 0 0 0 0;
}
}
.o_reconcile_models .btn-primary {
margin: 0 2px 3px 0;
}
/* Match view */
.match {
.cell_action .fa-add-remove:before {
content: "";
}
tr:hover .cell_action .fa-add-remove:before {
content: "\f067";
}
.match_controls {
padding: 5px 0 5px ($o-account-action-col-width+$o-account-main-table-borders-padding);
.filter {
width: 240px;
display: inline-block;
}
.fa-chevron-left, .fa-chevron-right {
display: inline-block;
cursor: pointer;
}
.fa-chevron-left {
margin-right: 10px;
}
.fa-chevron-left.disabled, .fa-chevron-right.disabled {
color: #ddd;
cursor: default;
}
}
.show_more {
display: inline-block;
margin-left: ($o-account-action-col-width+$o-account-main-table-borders-padding);
margin-top: 5px;
}
}
/* Create view */
.create {
> div > div.quick_add > .o_reconcile_models {
max-width: 100%;
max-height: 70px;
flex-wrap: wrap;
overflow: auto;
& > * {
flex-grow: 0;
}
}
.quick_add {
margin-bottom: 7px;
padding: 0 8px;
}
.o_group table.o_group_col_6 {
width: 49%;
margin: 0;
vertical-align: top;
}
.o_group table.o_group_col_6:first-child {
margin-left: 8px;
}
.btn {
padding-top: 0;
padding-bottom: 0;
}
.add_line_container {
text-align: center;
clear: both;
color: $o-enterprise-primary-color;
cursor: pointer;
}
}
.o_notebook .tab-content > .tab-pane {
padding: 5px 0;
}
}
/*Manual Reconciliation*/
.o_manual_statement {
.accounting_view {
td[colspan="3"] span:first-child {
width: 100%;
display: inline-block;
}
td[colspan="2"] {
border-bottom: 1px solid #333;
text-align: center;
width: 240px;
}
.do_partial_reconcile_true {
display: none;
}
}
}
// This is rtl language specific fix
// It will flip the fa-fa play icon in left direction
.o_rtl {
.o_reconciliation {
.o_reconciliation_line {
.toggle_match, .toggle_create {
transform: rotate(180deg);
transition: transform 300ms;
}
.visible_toggle, &[data-mode="match"] .toggle_match, &[data-mode="create"] .toggle_create {
transform: rotate(270deg);
}
}
}
}
.o_search_panel.account_root {
flex: 0 0 50px;
padding: 6px;
scrollbar-width: thin;
.o_search_panel_section_header {
display: none;
}
.list-group-item span.o_search_panel_label_title {
display: contents;
}
.o_search_panel_category_value {
header {
margin-left: 0;
padding-left: 0;
}
.o_search_panel_category_value .o_toggle_fold {
width: 0.3rem;
}
}
&::-webkit-scrollbar {
width: 4px;
}
&::-webkit-scrollbar-thumb {
background: lightgray;
}
}
// The goal of this file is to contain CSS hacks related to allowing
// section and note on sale order and invoice.
table.o_section_and_note_list_view tr.o_data_row.o_is_line_note,
table.o_section_and_note_list_view tr.o_data_row.o_is_line_note textarea[name="name"],
div.oe_kanban_card.o_is_line_note {
font-style: italic;
}
table.o_section_and_note_list_view tr.o_data_row.o_is_line_section,
div.oe_kanban_card.o_is_line_section {
font-weight: bold;
background-color: #DDDDDD;
}
table.o_section_and_note_list_view tr.o_data_row.o_is_line_section {
border-top: 1px solid #BBB;
border-bottom: 1px solid #BBB;
}
table.o_section_and_note_list_view tr.o_data_row {
&.o_is_line_note,
&.o_is_line_section {
td {
// There is an undeterministic CSS behaviour in Chrome related to
// the combination of the row's and its children's borders.
border: none !important;
}
}
}
$o-account-action-col-width: 15px;
$o-account-main-table-borders-padding: 3px;
$o-account-light-border: 1px solid #bbb;
$o-account-initial-line-background: #f0f0f0;
$o-account-info-color: #44c;
@keyframes animate-red {
0% {
color: red;
}
100% {
color: inherit;
}
}
.animate {
animation: animate-red 1s ease;
}
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<t t-name="accountJournalDashboardActivity">
<t t-foreach="activities" t-as="activity">
<div class="row">
<div class="col-8 o_mail_activity">
<a href="#"
t-att-class="(activity.status == 'late' ? 'o_activity_color_overdue ' : ' ') + (activity.activity_category == 'tax_report' ? 'o_open_vat_report' : 'see_activity')"
t-att-data-res-id="activity.res_id" t-att-data-id="activity.id"
t-att-data-model="activity.res_model">
<t t-esc="activity.name"/>
</a>
</div>
<div class="col-4 text-right">
<span>
<t t-esc="activity.date"/>
</span>
</div>
</div>
</t>
<a t-if="more_activities" class="pull-right see_all_activities" href="#">See all activities</a>
</t>
</templates>
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="ShowPaymentInfo">
<div>
<t t-if="outstanding">
<div>
<strong class="float-left" id="outstanding"><t t-esc="title"></t></strong>
</div>
</t>
<table style="width:100%;">
<t t-foreach="lines" t-as="line">
<tr>
<t t-if="outstanding">
<td>
<a title="assign to invoice" role="button"
class="oe_form_field btn btn-link outstanding_credit_assign" t-att-data-id="line.id"
style="margin-right: 10px;" href="#" data-toggle="tooltip">Add</a>
</td>
<td style="max-width: 30em;">
<div class="oe_form_field"
style="margin-right: 30px; text-overflow: ellipsis; overflow: hidden; white-space: nowrap;"
t-att-title="line.date" data-toggle="tooltip"><t t-esc="line.journal_name"></t></div>
</td>
</t>
<t t-if="!outstanding">
<td>
<a role="button" tabindex="0" class="js_payment_info fa fa-info-circle"
t-att-index="line.index" style="margin-right:5px;" aria-label="Info" title="Payment Info"
data-toggle="tooltip"></a>
</td>
<td>
<i class="o_field_widget text-right o_payment_label">Paid on <t t-esc="line.date"></t></i>
</td>
</t>
<td style="text-align:right;">
<span class="oe_form_field oe_form_field_float oe_form_field_monetary"
style="margin-left: -10px;">
<t t-if="line.position === 'before'">
<t t-esc="line.currency"/>
</t>
<t t-esc="line.amount"></t>
<t t-if="line.position === 'after'">
<t t-esc="line.currency"/>
</t>
</span>
</td>
</tr>
</t>
</table>
</div>
</t>
<t t-name="PaymentPopOver">
<div>
<table>
<tr>
<td><strong>Amount: </strong></td>
<td>
<t t-if="position === 'before'">
<t t-esc="currency"/>
</t>
<t t-esc="amount"></t>
<t t-if="position === 'after'">
<t t-esc="currency"/>
</t>
</td>
</tr>
<tr>
<td><strong>Memo: </strong></td>
<td>
<div style="width: 200px; word-wrap: break-word">
<t t-esc="ref"/>
</div>
</td>
</tr>
<tr>
<td><strong>Date: </strong></td>
<td><t t-esc="date"/></td>
</tr>
<tr>
<td><strong>Payment Journal: </strong></td>
<td><t t-esc="journal_name"/>
<span t-if="payment_method_name"> (<t t-esc="payment_method_name"/>)</span></td>
</tr>
</table>
</div>
<button class="btn btn-sm btn-primary js_unreconcile_payment float-left" t-att-partial-id="partial_id"
t-att-payment-id="payment_id" t-att-move-id="move_id" style="margin-top:5px; margin-bottom:5px;"
groups="account.group_account_invoice">Unreconcile</button>
<button class="btn btn-sm btn-secondary js_open_payment float-right" t-att-payment-id="account_payment_id"
t-att-move-id="move_id" style="margin-top:5px; margin-bottom:5px;">View</button>
</t>
</templates>
<?xml version="1.0" encoding="utf-8"?>
<templates>
<div t-name="account.ResequenceRenderer" owl="1" class="d-block">
<table t-if="data.changeLines.length" class="table table-sm">
<thead>
<tr>
<th>Date</th>
<th>Before</th>
<th>After</th>
</tr>
</thead>
<tbody t-foreach="data.changeLines" t-as="changeLine" t-key="changeLine.id">
<ChangeLine changeLine="changeLine" ordering="data.ordering"/>
</tbody>
</table>
</div>
<t t-name="account.ResequenceChangeLine" owl="1">
<tr>
<td t-esc="props.changeLine.date"/>
<td t-esc="props.changeLine.current_name"/>
<td t-if="props.ordering == 'keep'" t-esc="props.changeLine.new_by_name"
t-attf-class="{{ props.changeLine.new_by_name != props.changeLine.new_by_date ? 'animate' : ''}}"/>
<td t-else="" t-esc="props.changeLine.new_by_date"
t-attf-class="{{ props.changeLine.new_by_name != props.changeLine.new_by_date ? 'animate' : ''}}"/>
</tr>
</t>
</templates>
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<t t-name="account.BillsHiddenUploadForm">
<div class="d-none o_vendor_bill_upload">
<t t-call="HiddenInputFile">
<t t-set="multi_upload" t-value="true"/>
<t t-set="fileupload_id" t-value="widget.fileUploadID"/>
<t t-set="fileupload_action" t-translation="off">/web/binary/upload_attachment</t>
<input type="hidden" name="model" value=""/>
<input type="hidden" name="id" value="0"/>
</t>
</div>
</t>
<t t-extend="ListView.buttons" t-name="BillsListView.buttons">
<t t-jquery="button.o_list_button_add" t-operation="after">
<button type="button" class="btn btn-secondary o_button_upload_bill">
Upload
</button>
</t>
</t>
</templates>
<?xml version="1.0" encoding="utf-8"?>
<templates>
<div t-name="account.GroupedListTemplate" owl="1" class="d-block">
<table t-if="data.groups_vals.length"
class="table table-sm o_list_table table table-sm table-hover table-striped o_list_table_grouped">
<thead>
<tr>
<t t-foreach="data.options.columns" t-as="col">
<th t-esc="col['label']" t-attf-class="{{col['class']}}"/>
</t>
</tr>
</thead>
<t t-foreach="data.groups_vals" t-as="group_vals">
<ListGroup group_vals="group_vals" options="data.options"/>
</t>
</table>
<t t-if="data.options.discarded_number">
<span>
<t t-esc="data.options.discarded_number"/>
are not shown in the preview
</span>
</t>
</div>
<tbody t-name="account.GroupedItemsTemplate" owl="1">
<tr style="background-color: #dee2e6;">
<td t-attf-colspan="{{props.options.columns.length}}">
<t t-esc="props.group_vals.group_name"/>
</td>
</tr>
<t t-foreach="props.group_vals.items_vals" t-as="item_vals">
<ListItem item_vals="item_vals[2]" options="props.options"/>
</t>
</tbody>
<tr t-name="account.GroupedItemTemplate" owl="1">
<t t-foreach="props.options.columns" t-as="col">
<td t-esc="props.item_vals[col['field']]" t-attf-class="{{col['class']}}"/>
</t>
</tr>
</templates>
<?xml version='1.0' encoding='utf-8'?>
<templates>
<t t-name="AccountTaxGroupTemplate">
<table class="o_group o_inner_group oe_subtotal_footer border-0 my-0" style="min-width: 100%;">
<tbody>
<t t-foreach="lines" t-as="line">
<tr>
<td class="o_td_label oe_tax_group_name">
<label class="o_form_label" t-esc="line[0]"/>
</td>
<td class="oe_tax_group_editable" t-att-data-tax-group-id="line[6]">
<t t-if="displayEditWidget and line[1] !== 0">
<span class="tax_group_edit">
<i class="fa fa-pencil"></i>
<span class="oe_tax_group_amount_value">
<t t-esc="line[3]"/>
</span>
</span>
<span class="tax_group_edit_input d-none">
<input type="text" class="o_field_float o_field_number o_input"
t-att-data-original-value="line[1]"/>
</span>
</t>
<t t-if="!displayEditWidget or line[1] === 0">
<span class="oe_tax_group_amount_value">
<t t-esc="line[3]"/>
</span>
</t>
</td>
</tr>
</t>
</tbody>
</table>
</t>
</templates>
odoo.define('account.reconciliation_field_tests', function (require) {
"use strict";
var FormView = require('web.FormView');
var testUtils = require('web.test_utils');
var createView = testUtils.createView;
QUnit.module('account', {
beforeEach: function () {
this.data = {
'account.move': {
fields: {
payments_widget: {string: "payments_widget data", type: "char"},
outstanding_credits_debits_widget: {
string: "outstanding_credits_debits_widget data",
type: "char"
},
},
records: [{
id: 1,
payments_widget: '{"content": [{"digits": [69, 2], "currency": "$", "amount": 555.0, "name": "Customer Payment: INV/2017/0004", "date": "2017-04-25", "position": "before", "ref": "BNK1/2017/0003 (INV/2017/0004)", "payment_id": 22, "move_id": 10, "partial_id": 38, "journal_name": "Bank"}], "outstanding": false, "title": "Less Payment"}',
outstanding_credits_debits_widget: '{"content": [{"digits": [69, 2], "currency": "$", "amount": 100.0, "journal_name": "INV/2017/0004", "position": "before", "id": 20}], "move_id": 4, "outstanding": true, "title": "Outstanding credits"}',
}]
},
};
}
}, function () {
QUnit.module('Reconciliation');
QUnit.test('Reconciliation form field', async function (assert) {
assert.expect(5);
var form = await createView({
View: FormView,
model: 'account.move',
data: this.data,
arch: '<form>' +
'<field name="outstanding_credits_debits_widget" widget="payment"/>' +
'<field name="payments_widget" widget="payment"/>' +
'</form>',
res_id: 1,
mockRPC: function (route, args) {
if (args.method === 'js_remove_outstanding_partial') {
assert.deepEqual(args.args, [10, 38], "should call js_remove_outstanding_partial {warning: required focus}");
return Promise.resolve();
}
if (args.method === 'js_assign_outstanding_line') {
assert.deepEqual(args.args, [4, 20], "should call js_assign_outstanding_line {warning: required focus}");
return Promise.resolve();
}
return this._super.apply(this, arguments);
},
intercepts: {
do_action: function (event) {
assert.deepEqual(event.data.action, {
'type': 'ir.actions.act_window',
'res_model': 'account.move',
'res_id': 10,
'views': [[false, 'form']],
'target': 'current'
},
"should open the form view");
},
},
});
assert.strictEqual(form.$('.o_field_widget[name="payments_widget"]').text().replace(/[\s\n\r]+/g, ' '),
" Paid on 04/25/2017 $ 555.00 ",
"should display payment information");
form.$('.o_field_widget[name="outstanding_credits_debits_widget"] .outstanding_credit_assign').trigger('click');
assert.strictEqual(form.$('.o_field_widget[name="outstanding_credits_debits_widget"]').text().replace(/[\s\n\r]+/g, ' '),
" Outstanding credits Add INV/2017/0004 $ 100.00 ",
"should display outstanding information");
form.$('.o_field_widget[name="payments_widget"] .js_payment_info').trigger('focus');
form.$('.popover .js_open_payment').trigger('click');
form.$('.o_field_widget[name="payments_widget"] .js_payment_info').trigger('focus');
form.$('.popover .js_unreconcile_payment').trigger('click');
form.destroy();
});
});
});
odoo.define('account.section_and_note_tests', function (require) {
"use strict";
var FormView = require('web.FormView');
var testUtils = require('web.test_utils');
var createView = testUtils.createView;
QUnit.module('section_and_note', {
beforeEach: function () {
this.data = {
invoice: {
fields: {
invoice_line_ids: {
string: "Lines",
type: 'one2many',
relation: 'invoice_line',
relation_field: 'invoice_id'
},
},
records: [
{id: 1, invoice_line_ids: [1, 2]},
],
},
invoice_line: {
fields: {
display_type: {
string: 'Type',
type: 'selection',
selection: [['line_section', "Section"], ['line_note', "Note"]]
},
invoice_id: {
string: "Invoice",
type: 'many2one',
relation: 'invoice'
},
name: {
string: "Name",
type: 'text'
},
},
records: [
{id: 1, display_type: false, invoice_id: 1, name: 'product\n2 lines'},
{id: 2, display_type: 'line_section', invoice_id: 1, name: 'section'},
]
},
};
},
}, function () {
QUnit.test('correct display of section and note fields', async function (assert) {
assert.expect(5);
var form = await createView({
View: FormView,
model: 'invoice',
data: this.data,
arch: '<form>' +
'<field name="invoice_line_ids" widget="section_and_note_one2many"/>' +
'</form>',
archs: {
'invoice_line,false,list': '<tree editable="bottom">' +
'<field name="display_type" invisible="1"/>' +
'<field name="name" widget="section_and_note_text"/>' +
'</tree>',
},
res_id: 1,
});
assert.hasClass(form.$('[name="invoice_line_ids"] table'), 'o_section_and_note_list_view');
// section should be displayed correctly
var $tr0 = form.$('tr.o_data_row:eq(0)');
assert.doesNotHaveClass($tr0, 'o_is_line_section',
"should not have a section class");
var $tr1 = form.$('tr.o_data_row:eq(1)');
assert.hasClass($tr1, 'o_is_line_section',
"should have a section class");
// enter edit mode
await testUtils.form.clickEdit(form);
// editing line should be textarea
$tr0 = form.$('tr.o_data_row:eq(0)');
await testUtils.dom.click($tr0.find('td.o_data_cell'));
assert.containsOnce($tr0, 'td.o_data_cell textarea[name="name"]',
"editing line should be textarea");
// editing section should be input
$tr1 = form.$('tr.o_data_row:eq(1)');
await testUtils.dom.click($tr1.find('td.o_data_cell'));
assert.containsOnce($tr1, 'td.o_data_cell input[name="name"]',
"editing section should be input");
form.destroy();
});
});
});
odoo.define('account.dashboard.setup.tour', function (require) {
"use strict";
var core = require('web.core');
var tour = require('web_tour.tour');
var _t = core._t;
tour.register('account_render_report', {
test: true,
url: '/web',
}, [tour.stepUtils.showAppsMenuItem(),
{
id: 'account_menu_click',
trigger: '.o_app[data-menu-xmlid="account.menu_finance"]',
position: 'bottom',
}, {
trigger: '.o_data_row:first',
extra_trigger: '.breadcrumb',
}, {
trigger: '.o_control_panel button:contains("' + _t('Print') + '")',
}, {
trigger: '.o_control_panel .o_dropdown_menu a:contains("' + _t('Invoices without Payment') + '")',
}, {
trigger: 'iframe .o_report_layout_standard h2',
content: 'Primary color is correct',
run: function () {
if (this.$anchor.css('color') !== "rgb(18, 52, 86)") {
console.error('The primary color should be the one set on the company.');
}
},
}, {
trigger: 'iframe .o_report_layout_standard #informations div strong',
content: 'Secondary color is correct',
run: function () {
if (this.$anchor.css('color') !== "rgb(120, 145, 1)") {
console.error('The secondary color should be the one set on the company.');
}
},
}
]);
});
odoo.define('account.tax.group.tour.tests', function (require) {
"use strict";
var core = require('web.core');
var tour = require('web_tour.tour');
var _t = core._t;
tour.register('account_tax_group', {
test: true,
url: "/web",
}, [tour.stepUtils.showAppsMenuItem(),
{
content: "Go to Invoicing",
trigger: '.o_app[data-menu-xmlid="account.menu_finance"]',
edition: 'community',
},
{
content: "Go to Accounting",
trigger: '.o_app[data-menu-xmlid="account_accountant.menu_accounting"]',
edition: 'enterprise',
},
{
content: "Go to Vendors",
trigger: 'a:contains("Vendors")',
},
{
content: "Go to Bills",
trigger: 'span:contains("Bills")',
},
{
extra_trigger: '.breadcrumb:contains("Bills")',
content: "Create new bill",
trigger: '.o_list_button_add',
},
// Set a vendor
{
content: "Add vendor",
trigger: 'div.o_field_widget.o_field_many2one[name="partner_id"] div input',
run: 'text Azure Interior',
},
{
content: "Valid vendor",
trigger: '.ui-menu-item a:contains("Azure Interior")',
},
// Add First product
{
content: "Add items",
trigger: 'div[name="invoice_line_ids"] .o_field_x2many_list_row_add a:contains("Add a line")',
},
{
content: "Select input",
trigger: 'div[name="invoice_line_ids"] .o_list_view .o_selected_row .o_list_many2one:first input',
},
{
content: "Type item",
trigger: 'div[name="invoice_line_ids"] .o_list_view .o_selected_row .o_list_many2one:first input',
run: "text Large Desk",
},
{
content: "Valid item",
trigger: '.ui-menu-item-wrapper:contains("Large Desk")',
},
// Save account.move
{
content: "Save the account move",
trigger: '.o_form_button_save',
},
// Edit account.move
{
content: "Edit the account move",
trigger: '.o_form_button_edit',
},
// Edit tax group amount
{
content: "Edit tax group amount",
trigger: '.oe_tax_group_amount_value',
},
{
content: "Modify the input value",
trigger: '.tax_group_edit_input input',
run: function (actions) {
$('.tax_group_edit_input input').val(200);
$('.tax_group_edit_input input').select();
var keydownEvent = jQuery.Event('keydown');
keydownEvent.which = 13;
this.$anchor.trigger(keydownEvent);
},
},
// Check new value for total (with modified tax_group_amount).
{
content: "Valid total amount",
trigger: 'span[name="amount_total"]:contains("1,499.00")',
},
// Modify the quantity of the object
{
content: "Select item quantity",
trigger: 'div[name="invoice_line_ids"] .o_list_view tbody tr.o_data_row .o_list_number[title="1.000"]',
},
{
content: "Change item quantity",
trigger: 'div[name="invoice_line_ids"] .o_list_view tbody tr.o_data_row .o_list_number[title="1.000"] input',
run: 'text 2',
},
{
content: "Valid the new value",
trigger: 'div[name="invoice_line_ids"] .o_list_view tbody tr.o_data_row .o_list_number[title="1.000"] input',
run: function (actions) {
var keydownEvent = jQuery.Event('keydown');
keydownEvent.which = 13;
this.$anchor.trigger(keydownEvent);
},
},
// Save form
{
content: "Save the account move",
trigger: '.o_form_button_save',
},
// Check new tax group value
{
content: "Check new value of tax group",
trigger: '.oe_tax_group_amount_value:contains("389.70")',
},
]);
});
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="bphtb_jenis_tree" model="ir.ui.view">
<field name="name">bphtb.jenis.tree</field>
<field name="model">bphtb.jenis</field>
<field name="arch" type="xml">
<tree string="Jenis Perolehan" sample="1" create="1" delete="1" multi_edit="0">
<field name="code" string="Kode"/>
<field name="name" string="Nama"/>
<field name="rate" string="Tarif"/>
<field name="min_omzet" string="NJOPTKP"/>
<field name="disc" string="Pengurangan"/>
</tree>
</field>
</record>
<record id="bphtb_jenis_form" model="ir.ui.view">
<field name="name">bphtb.jenis.form</field>
<field name="model">bphtb.jenis</field>
<field name="arch" type="xml">
<form string="Jenis Perolehan" sample="1">
<sheet>
<h1>
<field name="name" string="Nama"/>
</h1>
<group>
<field name="code" string="Kode"/>
<field name="rate" string="Tarif"/>
<field name="min_omzet" string="NJOPTKP"/>
<field name="disc" string="Pengurangan"/>
<field name="company_id" groups="base.group_multi_company"
options="{'no_create': True}"
force_save="1"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="action_jenis_bphtb_kab" model="ir.actions.act_window">
<field name="name">Jenis Perolehan</field>
<field name="res_model">bphtb.jenis</field>
<field name="view_mode">kanban,tree,form</field>
<field name="view_id" ref="bphtb_jenis_tree"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Jenis Perolehan
</p>
</field>
</record>
</data>
</odoo>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Top menu item -->
<menuitem id="bphtb_menu_root"
name="BPHTB"
web_icon="bphtb_icon,static/description/icon.png"
active="True"
sequence="400"/>
<!-- Konfigurasi-->
<menuitem id="config_bphtb_menu"
name="Konfigurasi"
parent="bphtb_menu_root"
sequence="7"/>
<menuitem id="wilayah_config_bphtb_menu"
name="Wilayah"
parent="config_bphtb_menu"
sequence="2"/>
<menuitem id="state_config_bphtb_menu"
name="Provinsi"
parent="wilayah_config_bphtb_menu"
action="id_gov.action_state_config_id"
sequence="2"/>
<menuitem id="district_config_bphtb_menu"
name="Kabupaten/Kota"
parent="wilayah_config_bphtb_menu"
action="id_gov.action_district_config_id"
sequence="2"/>
<menuitem id="sub_district_config_bphtb_menu"
name="Kecamatan"
parent="wilayah_config_bphtb_menu"
action="id_gov.action_sub_district_config_id"
sequence="2"/>
<menuitem id="village_config_bphtb_menu"
name="Desa/Kelurahan"
parent="wilayah_config_bphtb_menu"
action="id_gov.action_village_config_id"
sequence="2"/>
<menuitem id="company_config_bphtb_menu"
name="Pemerintah Daerah/Organisasi"
parent="config_bphtb_menu"
action="id_gov.action_company_config_id"
sequence="4"/>
<menuitem id="jenis_config_bphtb_menu"
name="Jenis Perolehan"
parent="config_bphtb_menu"
action="action_jenis_bphtb_kab"
sequence="4"/>
<menuitem id="ppat_config_bphtb_menu"
name="PPAT"
parent="config_bphtb_menu"
action="action_ppat_config_bphtb_kab"
sequence="4"/>
<menuitem id="wp_config_bphtb_menu"
name="Wajib Pajak"
parent="config_bphtb_menu"
action="action_wp_config_bphtb_kab"
sequence="4"/>
<!-- Transaksi-->
<menuitem id="transaksi_bphtb_menu"
name="Transaksi"
parent="bphtb_menu_root"
sequence="6"/>
<menuitem id="sspd_bphtb_menu"
name="SSPD"
parent="transaksi_bphtb_menu"
action="action_sspd_bphtb_kab"
sequence="4"/>
</odoo>
<odoo>
<data>
<!-- <record id="res_partner_ppat_search" model="ir.ui.view">-->
<!-- <field name="name">res.partner.ppat.search.inherit</field>-->
<!-- <field name="model">res.partner</field>-->
<!-- <field name="inherit_id" ref="base.view_res_partner_filter"/>-->
<!-- <field name="arch" type="xml">-->
<!-- <xpath expr="//filter[@name='inactive']" position="before">-->
<!-- <filter string="PPAT" name="ppat" domain="[('type','=', 'ppat')]"/>-->
<!-- <filter string="Wajib Pajak" name="wp" domain="[('type','=', 'wp')]"/>-->
<!-- <separator/>-->
<!-- </xpath>-->
<!-- </field>-->
<!-- </record>-->
<record id="action_ppat_config_bphtb_kab" model="ir.actions.act_window">
<field name="name">PPAT</field>
<field name="res_model">res.partner</field>
<field name="view_mode">kanban,tree,form</field>
<field name="domain">[('type','=','ppat')]</field>
<field name="context">{
'default_is_company': True,
'default_type': 'ppat'}
</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Partner
</p>
</field>
</record>
<record id="action_wp_config_bphtb_kab" model="ir.actions.act_window">
<field name="name">Wajib Pajak</field>
<field name="res_model">res.partner</field>
<field name="view_mode">kanban,tree,form</field>
<field name="domain">[('type','=','wp')]</field>
<field name="context">{
'default_is_company': True,
'default_type': 'ppat'}
</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Partner
</p>
</field>
</record>
</data>
</odoo>
\ No newline at end of file
<odoo>
<data>
<record id="bphtb_sspd_tree" model="ir.ui.view">
<field name="name">bphtb.sspd.tree</field>
<field name="model">bphtb.sales</field>
<field name="arch" type="xml">
<tree string="SSPD" sample="1" create="1" delete="1" multi_edit="0">
<field name="nop" string="NOP"/>
<field name="tax_year" string="Tahun"/>
<field name="jenis_id" string="Jenis"/>
<field name="wp_id" string="Wajib Pajak"/>
<field name="owed" string="Terutang"/>
<field name="state" string="Status"/>
</tree>
</field>
</record>
<record id="bphtb_sspd_form" model="ir.ui.view">
<field name="name">bphtb.sspd.form</field>
<field name="model">bphtb.sales</field>
<field name="arch" type="xml">
<form string="Jenis Perolehan" sample="1">
<sheet>
<label for="nop" string="NOP"/>
<h1>
<field name="nop"/>
</h1>
<group>
<field name="tax_year"/>
<field name="request_date"/>
<field name="typ" readonly="1"/>
<field name="ppat_id"/>
<field name="state"/>
<field name="company_id"/>
</group>
<notebook col_span="4">
<page name="op" string="Objek Pajak">
<group>
<group>
<field name="luas_bumi"/>
<field name="luas_bng"/>
<field name="njop_bumi"/>
<field name="njop_bng"/>
</group>
<group>
<field name="luas_bumi_bersama"/>
<field name="luas_bng_bersama"/>
<field name="njop_bumi_bersama"/>
<field name="njop_bng_bersama"/>
<field name="certicate_no"/>
</group>
</group>
</page>
<page name="wp" string="Wajib Pajak">
<group>
<group>
<field name="wp_id"/>
<field name="wp_identity_number"/>
<label for="wp_street" string="Address"/>
<div class="o_address_format">
<field name="wp_street" placeholder="Street..." class="o_address_street"/>
<field name="wp_street2" placeholder="Street 2..."
class="o_address_street"/>
<field name="wp_village_id" class="o_address_city"
placeholder="Desa/Keurahan"
options="{'no_open': True, 'no_quick_create': True}"/>
<field name="wp_sub_district_id" class="o_address_city"
placeholder="Kecamatan"
options="{'no_open': True, 'no_quick_create': True}"/>
<field name="wp_district_id" class="o_address_city" placeholder="Kab/Kota"
options="{'no_open': True, 'no_quick_create': True}"/>
<field name="wp_state_id" class="o_address_city" placeholder="State"
options="{'no_open': True, 'no_quick_create': True}"/>
<field name="wp_zip" placeholder="ZIP" class="o_address_zip"/>
</div>
</group>
<group>
<field name="wp_email" placeholder="ZIP" class="o_address_zip"/>
<field name="wp_phone" placeholder="ZIP" class="o_address_zip"/>
</group>
</group>
</page>
<page name="seller" string="Penjual">
<group>
<group>
<field name="seller_id"/>
<field name="seller_identity_number"/>
<label for="seller_street" string="Address"/>
<div class="o_address_format">
<field name="seller_street" placeholder="Street..."
class="o_address_street"/>
<field name="seller_street2" placeholder="Street 2..."
class="o_address_street"/>
<field name="seller_village_id" class="o_address_city"
placeholder="Desa/Keurahan"
options="{'no_open': True, 'no_quick_create': True}"/>
<field name="seller_sub_district_id" class="o_address_city"
placeholder="Kecamatan"
options="{'no_open': True, 'no_quick_create': True}"/>
<field name="seller_district_id" class="o_address_city"
placeholder="Kab/Kota"
options="{'no_open': True, 'no_quick_create': True}"/>
<field name="seller_state_id" class="o_address_city" placeholder="State"
options="{'no_open': True, 'no_quick_create': True}"/>
<field name="seller_zip" placeholder="ZIP" class="o_address_zip"/>
</div>
</group>
<group>
<field name="seller_email" placeholder="ZIP" class="o_address_zip"/>
<field name="seller_phone" placeholder="ZIP" class="o_address_zip"/>
</group>
</group>
</page>
<page name="calc" string="Perhitungan">
<group>
<group>
<field name="jenis_id"/>
<field name="njop" readonly="1"/>
<field name="npop"/>
<field name="basic_calc" readonly="1"/>
<field name="min_omzet"/>
<field name="rate"/>
<field name="basic" readonly="1"/>
<field name="fine" readonly="1"/>
</group>
<group>
<!-- <label for="disc_sk" string="Pengurangan Dihitung Sendiri"/>-->
<!-- <group>-->
<field name="disc_sk"/>
<field name="disc"/>
<field name="amount" readonly="1"/>
<field name="payment"/>
<field name="disc_amount" readonly="1"/>
<field name="owed" readonly="1"/>
<!-- </group>-->
</group>
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record id="action_sspd_bphtb_kab" model="ir.actions.act_window">
<field name="name">SSPD</field>
<field name="res_model">bphtb.sales</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('typ','=','sspd')]</field>
<field name="view_id" ref="bphtb_sspd_tree"/>
<field name="context">{
'default_typ': 'sspd'}
</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Surat Setoran Pajak Daerah BPHTB
</p>
</field>
</record>
</data>
</odoo>
\ No newline at end of file
......@@ -22,6 +22,7 @@ Module yang sering digunakan dalam aplikasi pemerintah
'views/district.xml',
'views/partner.xml',
'views/company.xml',
'views/menus.xml',
],
'demo': [],
'qweb': [],
......
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Top menu item -->
<menuitem id="id_gov_menu_root"
name="Referensi"
web_icon="id_gov_icon,static/description/icon.png"
active="True"
sequence="400"/>
<menuitem id="wilayah_id_gov_menu"
name="Wilayah"
parent="id_gov_menu_root"
sequence="2"/>
<menuitem id="propinsi_menu"
name="Propinsi"
parent="wilayah_id_gov_menu"
action="action_state_config_id"
sequence="3"/>
<menuitem id="kota_menu"
name="Kabupaten/Kota"
parent="wilayah_id_gov_menu"
action="action_district_config_id"
sequence="4"/>
<menuitem id="kecamatan_menu"
name="Kecamatan"
parent="wilayah_id_gov_menu"
action="action_sub_district_config_id"
sequence="5"/>
<menuitem id="kelurahan_menu"
name="Kelurahan"
parent="wilayah_id_gov_menu"
action="action_village_config_id"
sequence="6"/>
</odoo>
......@@ -29,8 +29,9 @@ Menydiakan module untuk followup Wajib Pajak/Retribusi.
'views/menus.xml',
# 'security/account_security.xml',
# 'demo/demo_data.xml',
'demo/product.category.csv',
'security/ir_rule.xml',
'report/hide_default_report.xml',
'demo/product.category.csv',
],
'demo': [],
......
......@@ -8,9 +8,9 @@
<field name="report_name">product.report_productlabel</field>
<field name="report_file">product.report_productlabel</field>
<field name="print_report_name">'Products Labels - %s' % (object.name)</field>
<field name="binding_model_id" ref="product.model_product_product"/>
<!-- <field name="binding_model_id" ref="product.model_product_product"/>-->
<field name="binding_type">report</field>
<field name="menu">False</field>
<field name="binding_model_id" eval="False"/>
</record>
<record id="report_product_template_label" model="ir.actions.report">
......@@ -20,9 +20,9 @@
<field name="report_name">product.report_producttemplatelabel</field>
<field name="report_file">product.report_producttemplatelabel</field>
<field name="print_report_name">'Products Labels - %s' % (object.name)</field>
<field name="binding_model_id" ref="product.model_product_template"/>
<field name="binding_model_id" eval="False"/>
<!-- <field name="binding_model_id" ref="product.model_product_template"/>-->
<field name="binding_type">report</field>
<field name="menu">False</field>
</record>
<record id="report_product_product_barcode" model="ir.actions.report">
......@@ -32,9 +32,9 @@
<field name="report_name">product.report_productbarcode</field>
<field name="report_file">product.report_productbarcode</field>
<field name="print_report_name">'Products barcode - %s' % (object.name)</field>
<field name="binding_model_id" ref="product.model_product_product"/>
<field name="binding_model_id" eval="False"/>
<!-- <field name="binding_model_id" ref="product.model_product_product"/>-->
<field name="binding_type">report</field>
<field name="menu">False</field>
</record>
<record id="report_product_template_barcode" model="ir.actions.report">
......@@ -44,9 +44,10 @@
<field name="report_name">product.report_producttemplatebarcode</field>
<field name="report_file">product.report_producttemplatebarcode</field>
<field name="print_report_name">'Products barcode - %s' % (object.name)</field>
<field name="binding_model_id" ref="product.model_product_template"/>
<field name="binding_model_id" eval="False"/>
<!-- <field name="binding_model_id" ref="product.model_product_template"/>-->
<field name="binding_type">report</field>
<field name="menu">False</field>
</record>
<record id="report_product_packaging" model="ir.actions.report">
......@@ -56,9 +57,9 @@
<field name="report_name">product.report_packagingbarcode</field>
<field name="report_file">product.report_packagingbarcode</field>
<field name="print_report_name">'Products packaging - %s' % (object.name)</field>
<field name="binding_model_id" ref="product.model_product_packaging"/>
<field name="binding_model_id" eval="False"/>
<!-- <field name="binding_model_id" ref="product.model_product_packaging"/>-->
<field name="binding_type">report</field>
<field name="menu">False</field>
</record>
<record id="action_report_pricelist" model="ir.actions.report">
......@@ -67,8 +68,7 @@
<field name="report_type">qweb-pdf</field>
<field name="report_name">product.report_pricelist</field>
<field name="report_file">product.report_pricelist</field>
<field name="menu">False</field>
<field name="binding_model_id" eval="False"/>
</record>
</data>
</odoo>
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!