This commit is contained in:
Duy Dat 2025-06-21 09:44:01 +07:00
parent 7819a1d6db
commit 446d1f7d9d
112 changed files with 4951 additions and 8 deletions

62
.gitignore vendored Normal file
View File

@ -0,0 +1,62 @@
# sphinx build directories
_build/
# dotfiles
.*
!.gitignore
!.github
!.gitea
!.mailmap
# compiled python files
*.py[co]
__pycache__/
# setup.py egg_info
*.egg-info
# emacs backup files
*~
# hg stuff
*.orig
status
# odoo filestore
odoo/filestore
# maintenance migration scripts
odoo/addons/base/maintenance
# window installation config file
/odoo.conf
/*.conf
# generated for windows installer?
install/win32/*.bat
install/win32/meta.py
# needed only when building for win32
setup/win32/static/less/
setup/win32/static/wkhtmltopdf/
setup/win32/static/postgresql*.exe
# js tooling
node_modules
jsconfig.json
tsconfig.json
package-lock.json
package.json
.husky
# various virtualenv
/bin/
/build/
/dist/
/include/
/lib/
/man/
/share/
/src/
/deployment/postgresql/*
/venv*/
/deployment/backup/*.zip
/extra-addons/
*.pyc
/pragtech_hotel_management_addons/
pragtech_hotel_management_addons
*cache.json
odoo_backups
*.log

View File

@ -26,7 +26,6 @@ class LoanTypes(models.Model):
"""Create different types of Loans, And can wisely choose while requesting
for loan"""
_name = 'loan.type'
_inherit = ['mail.thread']
_description = 'Loan Type'
name = fields.Char(string='Name', help="LoanType Name", required=True)

View File

@ -43,7 +43,7 @@ class ResPartner(models.Model):
'type': 'ir.actions.act_window',
'name': 'Loans',
'view_mode': 'tree',
'res_model': 'loan.request',
'res_model': 'loan.request',
'domain': [('partner_id', '=', self.id)],
'context': "{'create': False}"
}

View File

@ -2,4 +2,5 @@
from . import controllers
from . import models
from . import wizard
from . import security

View File

@ -18,7 +18,7 @@ Long description of module's purpose
'version': '0.1',
# any module necessary for this one to work correctly
'depends': ['base'],
'depends': ['base','contacts'],
# always loaded
'data': [

View File

@ -7,7 +7,6 @@ class MyReport(models.AbstractModel):
def _get_report_values(self, docids, data=None):
# Lấy tất cả bản ghi employee.profile
docs = self.env['employee.profile'].browse(docids)
return {
'doc_model': 'employee.profile',
'docs': docs,

View File

@ -7,7 +7,6 @@
<field name="description">Access rights for employee management</field>
<field name="sequence">10</field>
</record>
<!-- Admin Group -->
<record id="group_employee_admin" model="res.groups">
<field name="name">Employee Admin</field>

View File

@ -1,5 +1,5 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_employee_profile_user,employee.profile,model_employee_profile,employee_management.group_employee_user,1,0,0,0
access_employee_profile_user,employee.profile,model_employee_profile,employee_management.group_employee_user,1,1,1,1
access_employee_profile_admin,employee.profile,model_employee_profile,employee_management.group_employee_admin,1,1,1,1
access_add_employee_wizard_user,add.employee.wizard,model_add_employee_wizard,employee_management.group_employee_user,0,0,0,0
access_add_employee_wizard_user,add.employee.wizard,model_add_employee_wizard,employee_management.group_employee_user,1,1,1,1
access_add_employee_wizard_admin,add.employee.wizard,model_add_employee_wizard,employee_management.group_employee_admin,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_employee_profile_user employee.profile model_employee_profile employee_management.group_employee_user 1 0 1 0 1 0 1
3 access_employee_profile_admin employee.profile model_employee_profile employee_management.group_employee_admin 1 1 1 1
4 access_add_employee_wizard_user add.employee.wizard model_add_employee_wizard employee_management.group_employee_user 0 1 0 1 0 1 0 1
5 access_add_employee_wizard_admin add.employee.wizard model_add_employee_wizard employee_management.group_employee_admin 1 1 1 1

View File

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
from . import controllers
from . import models
from . import wizards

View File

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
{
'name': "loan_management",
'summary': "Short (1 phrase/line) summary of the module's purpose",
'description': """
Long description of module's purpose
""",
'author': "My Company",
'website': "https://www.yourcompany.com",
# Categories can be used to filter modules in modules listing
# Check https://github.com/odoo/odoo/blob/15.0/odoo/addons/base/data/ir_module_category_data.xml
# for the full list
'category': 'Finance',
'version': '0.1',
# any module necessary for this one to work co rrectly
'depends': ['base','contacts','web'],
# always loaded
'data': [
"security/ir.model.access.csv",
'data/loan_sequence.xml',
'views/loan_type_views.xml',
'views/menu_items.xml',
'views/loan_borrower_view.xml',
'views/loan_interest_policy_views.xml',
'views/loan_request_view.xml',
],
"assets": {
"web.assets_backend": [
"loan_management/static/src/xml/res_config_edition.xml",
],
},
# only loaded in demonstration mode
'demo': [
'demo/demo.xml',
],
"installable": True,
"application": True,
}

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import controllers

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# from odoo import http
# class LoanManagement(http.Controller):
# @http.route('/loan_management/loan_management', auth='public')
# def index(self, **kw):
# return "Hello, world"
# @http.route('/loan_management/loan_management/objects', auth='public')
# def list(self, **kw):
# return http.request.render('loan_management.listing', {
# 'root': '/loan_management/loan_management',
# 'objects': http.request.env['loan_management.loan_management'].search([]),
# })
# @http.route('/loan_management/loan_management/objects/<model("loan_management.loan_management"):obj>', auth='public')
# def object(self, obj, **kw):
# return http.request.render('loan_management.object', {
# 'object': obj
# })

View File

@ -0,0 +1,14 @@
<odoo>
<data noupdate="1">
<record id="seq_loan_contract" model="ir.sequence">
<field name="name">Loan Contract Sequence</field>
<field name="code">loan.contract</field>
<field name="prefix">HĐ%(year)s</field>
<field name="padding">4</field>
<field name="number_next">1</field>
<field name="number_increment">1</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,30 @@
<odoo>
<data>
<!--
<record id="object0" model="loan_management.loan_management">
<field name="name">Object 0</field>
<field name="value">0</field>
</record>
<record id="object1" model="loan_management.loan_management">
<field name="name">Object 1</field>
<field name="value">10</field>
</record>
<record id="object2" model="loan_management.loan_management">
<field name="name">Object 2</field>
<field name="value">20</field>
</record>
<record id="object3" model="loan_management.loan_management">
<field name="name">Object 3</field>
<field name="value">30</field>
</record>
<record id="object4" model="loan_management.loan_management">
<field name="name">Object 4</field>
<field name="value">40</field>
</record>
-->
</data>
</odoo>

View File

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
from . import loan_type
from . import borrower
from . import loan_interest_policy
from . import loan_request

View File

@ -0,0 +1,19 @@
from odoo import models, fields
class ResPartner(models.Model):
_inherit = 'res.partner'
is_borrower = fields.Boolean(string='Is Borrower',default=True)
gender = fields.Selection([
('male', 'Male'),
('female', 'Female'),
('other', 'Other')
], string='Gender')
date_of_birth = fields.Date(string='Date of Birth')
job = fields.Char(string='Occupation')
monthly_income = fields.Float(string='Monthly Income')
marital_status = fields.Selection([
('single', 'Single'),
('married', 'Married'),
('divorced', 'Divorced'),
('widowed', 'Widowed'),
], string='Marital Status')

View File

@ -0,0 +1,176 @@
from odoo import models, fields, api
from dateutil.relativedelta import relativedelta
class LoanContract(models.Model):
_name = 'loan.contract'
_description = 'Loan Contract'
code_contract = fields.Char(
string='Contract Code',
required=True,
copy=False,
readonly=True,
default=lambda self: self.env['ir.sequence'].next_by_code('loan.contract')
)
repayment_line_ids = fields.One2many('repayment.line', 'contract_id', string='Lịch trả nợ')
loan_request_id = fields.Many2one(
'loan.request',
string='Loan Request',
required=True,
ondelete='restrict'
)
borrower_id = fields.Many2one(
'loan.borrower',
string='Borrower',
required=True,
ondelete='restrict'
)
loan_type_id = fields.Many2one(
'loan.type1',
string='Loan Type',
readonly=True
)
amount = fields.Float(
string='Loan Amount',
required=True
)
term = fields.Integer(
string='Term (Months)',
required=True
)
payment_method = fields.Selection([
('cash', 'Cash'),
('bank_transfer', 'Bank Transfer'),
('check', 'Check')
], string='Payment Method', required=True, default='cash',readonly=True)
repayment_type = fields.Selection([
('fixed_principal', 'Trả gốc đều, lãi giảm dần'),
('annuity', 'Trả góp đều (gốc + lãi)'),
('interest_only', 'Chỉ trả lãi hàng kỳ, gốc trả cuối'),
('lump_sum', 'Trả 1 lần cuối kỳ'),
], string='Kiểu trả nợ', required=True, readonly=True)
interest_rate = fields.Float(
string='Interest Rate (%)',
required=True
)
processing_fee = fields.Float(
string='Processing Fee',
compute='_compute_processing_fee_amount_count',
store=True,
readonly=True
)
amount_count = fields.Float(
string='Amount Count',
compute='_compute_processing_fee_amount_count',
store=True,
readonly=True
)
start_date = fields.Date(
string='Start Date',
required=True,
default=fields.Date.context_today
)
end_date = fields.Date(
string='End Date',
compute='_compute_end_date',
store=True,
readonly=True,
)
state = fields.Selection([
('draft', 'Draft'),
('active', 'Active'),
('done', 'Completed'),
('cancelled', 'Cancelled')
], string='Status', default='draft')
note = fields.Text(string='Notes')
@api.depends('start_date', 'term')
def _compute_end_date(self):
for rec in self:
if rec.start_date and rec.term:
rec.end_date = rec.start_date + relativedelta(months=rec.term)
else:
rec.end_date = False
@api.onchange('loan_request_id')
def _onchange_loan_request_id(self):
for rec in self:
if rec.loan_request_id:
rec.borrower_id = rec.loan_request_id.borrower_id
rec.loan_type_id = rec.loan_request_id.loan_type_id
rec.amount = rec.loan_request_id.amount
rec.interest_rate = rec.loan_request_id.interest_rate
rec.term = rec.loan_request_id.term
rec.repayment_type = rec.loan_request_id.repayment_type
@api.depends('loan_request_id')
def _compute_processing_fee_amount_count(self):
for rec in self:
if rec.loan_request_id:
rec.tinterest_rate = rec.loan_request_id.interest_rate or 0.0
rec.amount = rec.loan_request_id.amount or 0.0
rec.processing_fee = rec.amount - (rec.amount * rec.rate / 100)
rec.amount_count = rec.amount + rec.processing_fee
else:
rec.processing_fee = 0.0
rec.amount_count = 0.0
@api.model
def create(self, vals):
if vals.get('loan_request_id'):
request = self.env['loan.request'].browse(vals['loan_request_id'])
vals['repayment_type'] = request.repayment_type
vals['payment_method'] = request.payment_method
return super().create(vals)
@api.model
def write(self, vals):
res = super().write(vals)
for contract in self:
if vals.get('state') == 'active':
contract._generate_repayment_schedule()
return res
def _generate_repayment_schedule(self):
self.repayment_line_ids.unlink() # Xóa cũ nếu có
start_date = self.start_date
monthly_rate = self.interest_rate / 100 / 12
principal = self.amount
term = self.term
for i in range(1, term + 1):
due_date = start_date + relativedelta(months=i)
if self.repayment_type == 'fixed_principal':
principal_amount = principal / term
remaining = principal - principal_amount * (i - 1)
interest = remaining * monthly_rate
elif self.repayment_type == 'annuity':
annuity = principal * monthly_rate / (1 - (1 + monthly_rate) ** (-term))
interest = (principal - (i - 1) * (annuity - principal * monthly_rate)) * monthly_rate
principal_amount = annuity - interest
elif self.repayment_type == 'interest_only':
principal_amount = 0.0 if i < term else principal
interest = principal * monthly_rate
elif self.repayment_type == 'lump_sum':
principal_amount = principal if i == term else 0.0
interest = principal * monthly_rate if i == term else 0.0
else:
principal_amount = interest = 0.0
self.env['repayment.line'].create({
'contract_id': self.id,
'installment': i,
'due_date': due_date,
'principal': principal_amount,
'interest': interest,
'total': principal_amount + interest,
})

View File

@ -0,0 +1,18 @@
from odoo import models, fields
class LoanInterestPolicy(models.Model):
_name = 'loan.interest.policy'
_description = 'Loan Interest Policy'
loan_type_id = fields.Many2one('loan.type1', string='Loại khoản vay', required=True)
repayment_type = fields.Selection([
('fixed_principal', 'Gốc đều, lãi giảm dần'),
('annuity', 'Trả góp cố định'),
('interest_only', 'Chỉ trả lãi'),
('lump_sum', 'Trả 1 lần cuối kỳ'),
], string='Kiểu trả nợ', required=True)
interest_rate = fields.Float(string='Lãi suất (%)', required=True)
_sql_constraints = [
('unique_policy', 'unique(loan_type_id, repayment_type)', 'Chính sách lãi suất đã tồn tại cho loại vay và kiểu trả nợ này.')
]

View File

@ -0,0 +1,39 @@
from odoo import models, fields, api
class LoanRequest(models.Model):
_name = 'loan.request'
_description = 'Loan Request'
borrower_id = fields.Many2one('loan.borrower', string='Borrower', required=True, ondelete='restrict')
loan_type_id = fields.Many2one('loan.type1', string='Loan Type', required=True)
amount = fields.Float(string='Loan Amount', required=True)
term = fields.Integer(string='Term (months)', required=True,default=1)
repayment_type = fields.Selection([
('fixed_principal', 'Gốc đều, lãi giảm dần'),
('annuity', 'Trả góp cố định'),
('interest_only', 'Chỉ trả lãi'),
('lump_sum', 'Trả 1 lần cuối kỳ'),
], string='Kiểu trả nợ', required=True)
interest_rate = fields.Float(string='Interest Rate (%)', required=True)
expected_interest_rate = fields.Float(string='Lãi suất mong muốn', help="Khách hàng đề xuất một lãi suất thấp hơn nếu có")
payment_method = fields.Selection([
('cash', 'Cash'),
('bank_transfer', 'Bank Transfer'),
('check', 'Check')
], string='Payment Method', required=True, default='cash')
request_datetime = fields.Datetime(
string='Ngày giờ yêu cầu',
default=fields.Datetime.now)
state = fields.Selection([
('draft', 'Nháp'),
('processing', 'Đang xử lý'),
('approved', 'Đã duyệt'),
('rejected', 'Từ chối')
], string='Trạng thái', default='processing', required=True)
# def _onchange_interest_rate(self):
# if self.loan_type_id and self.repayment_type:
# policy = self.env['loan.interest.policy'].search([
# ('loan_type_id', '=', self.loan_type_id.id),
# ('repayment_type', '=', self.repayment_type)
# ], limit=1)
# self.interest_rate = policy.interest_rate if policy else 0.0

View File

@ -0,0 +1,15 @@
from odoo import api, models, fields
class LoanType(models.Model):
_name = 'loan.type1'
_description = 'Loan Type'
name = fields.Char(string='Loan Type', required=True,unique=True)
active = fields.Boolean(default=True)
interest_policy_ids = fields.One2many(
'loan.interest.policy',
'loan_type_id',
string='Chính sách lãi suất'
)
@api.onchange('name')
def _onchange_name_uppercase(self):
if self.name:
self.name = self.name.upper()

View File

@ -0,0 +1,15 @@
from odoo import models, fields
class RepaymentLine(models.Model):
_name = 'repayment.line'
_description = 'Repayment Schedule Line'
contract_id = fields.Many2one('loan.contract', string='Contract', ondelete='cascade', required=True)
installment = fields.Integer(string='Kỳ thứ')
due_date = fields.Date(string='Ngày đến hạn')
principal = fields.Float(string='Tiền gốc')
interest = fields.Float(string='Tiền lãi')
total = fields.Float(string='Tổng phải trả')
state = fields.Selection([
('draft', 'Chưa trả'),
('paid', 'Đã trả'),
], default='draft')

View File

@ -0,0 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_loan_type_user,access.loan.type.user,model_loan_type1,base.group_user,1,1,1,1
access_loan_interest_policy_user,access.loan.interest.policy.user,model_loan_interest_policy,base.group_user,1,1,1,1
access_loan_request_user,access.loan.request.user,model_loan_request,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_loan_type_user access.loan.type.user model_loan_type1 base.group_user 1 1 1 1
3 access_loan_interest_policy_user access.loan.interest.policy.user model_loan_interest_policy base.group_user 1 1 1 1
4 access_loan_request_user access.loan.request.user model_loan_request base.group_user 1 1 1 1

View File

@ -0,0 +1,10 @@
import { registry } from "@web/core/registry";
import { Component } from "@odoo/owl";
class HideResConfigEdition extends Component {
static template = "loan_management.hide_res_config_edition";
}
registry.category("view_widgets").add("res_config_edition", {
component: HideResConfigEdition,
});

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<templates xml:space="preserve">
<!-- Ẩn template res_config_edition -->
<t t-inherit="res_config_edition" t-inherit-mode="extension">
<xpath expr="//div[1]" position="replace">
<div t-if="False"/>
</xpath>
</t>
<!-- Ẩn template MobileAppsFunnel -->
<t t-inherit="web.MobileAppsFunnel" t-inherit-mode="extension">
<xpath expr="//div[1]" position="replace">
<div t-if="False"/>
</xpath>
</t>
</templates>

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Tree View -->
<record id="view_partner_borrower_tree" model="ir.ui.view">
<field name="name">res.partner.borrower.tree</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_tree"/>
<field name="arch" type="xml">
<xpath expr="//list" position="inside">
<field name="is_borrower"/>
<field name="name"/>
<field name="email"/>
<field name="phone"/>
<field name="monthly_income"/>
</xpath>
</field>
</record>
<!-- Form View -->
<record id="view_partner_borrower_form" model="ir.ui.view">
<field name="name">res.partner.borrower.form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="//notebook" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//sheet/group[1]" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//sheet" position="inside">
<group string="Borrower Information">
<field name="is_borrower"/>
<field name="name"/>
<field name="email"/>
<field name="phone"/>
<field name="gender"/>
<field name="date_of_birth"/>
<field name="job"/>
<field name="monthly_income"/>
<field name="marital_status"/>
</group>
</xpath>
</field>
</record>
<!-- Action -->
<record id="action_borrower_res_partner" model="ir.actions.act_window">
<field name="name">Borrowers</field>
<field name="res_model">res.partner</field>
<field name="view_mode">list,form</field>
<field name="domain">[('is_borrower','=',True)]</field>
<field name="context">{'default_is_borrower': True}</field>
</record>
<menuitem id="menu_loan_borrower" name="Borrowers" parent="loan_management.menu_loan_root" action="action_borrower_res_partner" sequence="2"/>
</odoo>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<!-- Tree View -->
<record id="view_loan_interest_policy_tree" model="ir.ui.view">
<field name="name">loan.interest.policy.tree</field>
<field name="model">loan.interest.policy</field>
<field name="arch" type="xml">
<list string="Loan Interest Policies">
<field name="loan_type_id"/>
<field name="repayment_type"/>
<field name="interest_rate"/>
</list>
</field>
</record>
<!-- Form View -->
<record id="view_loan_interest_policy_form" model="ir.ui.view">
<field name="name">loan.interest.policy.form</field>
<field name="model">loan.interest.policy</field>
<field name="arch" type="xml">
<form string="Loan Interest Policy">
<sheet>
<group>
<field name="loan_type_id"/>
<field name="repayment_type"/>
<field name="interest_rate"/>
</group>
</sheet>
</form>
</field>
</record>
<!-- Action -->
<record id="action_loan_interest_policy" model="ir.actions.act_window">
<field name="name">Loan Interest Policies</field>
<field name="res_model">loan.interest.policy</field>
<field name="view_mode">list,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create and manage loan interest policies.
</p>
</field>
</record>
</odoo>

View File

@ -0,0 +1,58 @@
<odoo>
<record id="view_loan_request_list" model="ir.ui.view">
<field name="name">loan.request.list</field>
<field name="model">loan.request</field>
<field name="arch" type="xml">
<list string="Danh sách yêu cầu vay vốn">
<field name="borrower_id"/>
<field name="loan_type_id"/>
<field name="amount"/>
<field name="term"/>
<field name="interest_rate"/>
<field name="payment_method"/>
<field name="state"/>
<field name="request_datetime"/>
</list>
</field>
</record>
<record id="view_loan_request_form" model="ir.ui.view">
<field name="name">loan.request.form</field>
<field name="model">loan.request</field>
<field name="arch" type="xml">
<form string="Gửi Yêu Cầu Vay Vốn">
<sheet>
<group>
<group>
<field name="borrower_id"/>
<field name="loan_type_id"/>
<field name="repayment_type"/>
<field name="amount"/>
<field name="term"/>
<field name="interest_rate"/>
<field name="expected_interest_rate"/>
</group>
<group>
<field name="payment_method"/>
<field name="request_datetime" readonly="1"/>
<field name="state" readonly="1"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<!-- Action để mở form -->
<record id="action_loan_request" model="ir.actions.act_window">
<field name="name">Yêu Cầu Vay Vốn</field>
<field name="res_model">loan.request</field>
<field name="view_mode">list,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Tạo yêu cầu vay vốn đầu tiên
</p>
</field>
</record>
</odoo>

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="view_loan_type_form" model="ir.ui.view">
<field name="name">loan.type.form</field>
<field name="model">loan.type1</field>
<field name="arch" type="xml">
<form string="Loan Type1">
<group>
<group>
<strong>
<field name="name" readonly="true" class="o_text_bold o_text_large"/>
</strong>
</group>
<group>
<field name="active"/>
</group>
</group>
<!-- Notebook nằm dưới -->
<notebook>
<page string="Thông tin chính sách vay nợ">
<field name="interest_policy_ids">
<list editable="bottom">
<field name="repayment_type"/>
<field name="interest_rate"/>
</list>
</field>
</page>
<!-- Bạn có thể thêm nhiều page khác nếu cần -->
</notebook>
</form>
</field>
</record>
<record id="view_loan_type1_list" model="ir.ui.view">
<field name="name">loan.type1.list</field>
<field name="model">loan.type1</field>
<field name="arch" type="xml">
<list string="Loan Types">
<field name="name"/>
<field name="active"/>
<field name="interest_policy_ids"></field>
</list>
</field>
</record>
<record id="action_loan_type" model="ir.actions.act_window">
<field name="name">Loan Types</field>
<field name="res_model">loan.type1</field>
<field name="view_mode">list,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Tạo các loại hình vay vốn tại đây.
</p>
</field>
</record>
</odoo>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Menu cha -->
<menuitem id="menu_loan_root" name="Loan Management" sequence="10"/>
<!-- Menu con liên kết tới action -->
<menuitem id="menu_loan_type_root" name="Loan Types" parent="menu_loan_root" sequence="1"/>
<menuitem id="menu_loan_tpe" name="kiểu vay vốn" parent="menu_loan_type_root" action="action_loan_type" sequence="1"/>
<menuitem id="menu_loan_interest_policy" name="chính sách vay vốn" parent="menu_loan_type_root" action="action_loan_interest_policy" sequence="2"/>
<menuitem id="menu_loan_borrower" name="Borrowers" parent="menu_loan_root" action="action_borrower_res_partner" sequence="2"/>
<menuitem id="menu_loan_request" name="Resquests" parent="menu_loan_root" action="action_loan_request" sequence="3"/>
</odoo>

View File

@ -0,0 +1,13 @@
from odoo import models, fields
class LoanRepaymentPreviewLine(models.TransientModel):
_name = 'loan.repayment.preview.line'
_description = 'Chi tiết dự kiến lịch trả nợ'
wizard_id = fields.Many2one('loan.repayment.preview.wizard', string='Wizard')
installment = fields.Integer(string='Kỳ số')
due_date = fields.Date(string='Ngày đến hạn')
principal = fields.Float(string='Gốc')
interest = fields.Float(string='Lãi')
total = fields.Float(string='Tổng')

View File

@ -0,0 +1 @@
from . import loan_repayment_preview_wizard,Loan_repayment_preview_line

View File

@ -0,0 +1,59 @@
from odoo import models, fields
from dateutil.relativedelta import relativedelta
class LoanRepaymentPreviewWizard(models.TransientModel):
_name = 'loan.repayment.preview.wizard'
_description = 'Loan Repayment Preview Wizard'
loan_request_id = fields.Many2one('loan.request', string='Yêu cầu vay', required=True)
preview_line_ids = fields.One2many('loan.repayment.preview.line', 'wizard_id', string='Chi tiết lịch trả', readonly=True)
def action_generate_preview_schedule(self):
self.ensure_one()
request = self.loan_request_id
self.preview_line_ids.unlink() # Clear old preview lines
amount = request.amount
term = request.term
rate = request.interest_rate
repayment_type = request.repayment_type
start_date = request.request_datetime.date() or fields.Date.today()
for i in range(term):
due_date = start_date + relativedelta(months=i + 1)
if repayment_type == 'fixed_principal':
principal = amount / term
interest = (amount - principal * i) * rate / 100 / 12
total = principal + interest
elif repayment_type == 'annuity':
monthly_rate = rate / 100 / 12
if monthly_rate == 0:
annuity = amount / term
else:
annuity = (amount * monthly_rate) / (1 - (1 + monthly_rate) ** -term)
interest = (amount - i * (amount / term)) * monthly_rate
principal = annuity - interest
total = annuity
elif repayment_type == 'interest_only':
principal = amount if i == term - 1 else 0
interest = amount * rate / 100 / 12
total = principal + interest
elif repayment_type == 'lump_sum':
principal = amount if i == term - 1 else 0
interest = amount * rate / 100 / 12
total = principal + interest
self.env['loan.repayment.preview.line'].create({
'wizard_id': self.id,
'installment': i + 1,
'due_date': due_date,
'principal': round(principal, 2),
'interest': round(interest, 2),
'total': round(total, 2),
})

View File

@ -0,0 +1,32 @@
<odoo>
<record id="view_loan_repayment_preview_wizard_form" model="ir.ui.view">
<field name="name">loan.repayment.preview.wizard.form</field>
<field name="model">loan.repayment.preview.wizard</field>
<field name="arch" type="xml">
<form string="Xem trước lịch trả nợ" create="false" edit="false">
<group>
<field name="loan_request_id" readonly="1"/>
</group>
<field name="preview_line_ids">
<tree editable="false">
<field name="installment"/>
<field name="due_date"/>
<field name="principal"/>
<field name="interest"/>
<field name="total"/>
</tree>
</field>
<footer>
<button string="Đóng" special="cancel" class="btn-secondary"/>
</footer>
</form>
</field>
</record>
<record id="action_loan_repayment_preview_wizard" model="ir.actions.act_window">
<field name="name">Xem lịch trả nợ</field>
<field name="res_model">loan.repayment.preview.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</odoo>

View File

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from . import controllers
from . import models

View File

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
{
'name': "website_genhd_embeb",
'summary': "Short (1 phrase/line) summary of the module's purpose",
'description': """
Long description of module's purpose
""",
'author': "My Company",
'website': "https://www.yourcompany.com",
# Categories can be used to filter modules in modules listing
# Check https://github.com/odoo/odoo/blob/15.0/odoo/addons/base/data/ir_module_category_data.xml
# for the full list
'category': 'Uncategorized',
'version': '0.1',
# any module necessary for this one to work correctly
'depends': ['website'],
'assets': {
'web.assets_frontend': [
'website_genhd_embeb/static/css/bootstrap.min.css',
'website_genhd_embeb/static/css/bootstrap-icons.css',
'website_genhd_embeb/static/css/owl.carousel.min.css',
'website_genhd_embeb/static/css/tooplate-moso-interior.css',
'https://fonts.googleapis.com/css2?family=League+Spartan:wght@100;300;400;600;700&display=swap',
'website_genhd_embeb/static/js/bootstrap.min.js',
'website_genhd_embeb/static/js/click-scroll.js',
'website_genhd_embeb/static/js/jquery.backstretch.min.js',
'website_genhd_embeb/static/js/owl.carousel.min.js',
'website_genhd_embeb/static/js/custom.js',
"website_genhd_embeb/static/css/Backend_server.css"
],
},
# always loaded
'data': [
'security/ir.model.access.csv',
"views/custom_homepage.xml",
"views/frontend_views/website_moso_homePage.xml",
"views/frontend_views/nav_template.xml",
"views/frontend_views/footer_template.xml",
"views/frontend_views/website_moso_productList.xml",
"views/frontend_views/website_moso_detail.xml",
"views/frontend_views/webstie_moso_oder.xml",
"views/Backend_views/menu_items.xml",
"views/Backend_views/moso_category_view.xml",
"views/Backend_views/moso_condition_view.xml",
"views/Backend_views/moso_type_view.xml",
"views/Backend_views/moso_product_view.xml",
],
# only loaded in demonstration mode
'demo': [
'demo/demo.xml',
],
}

View File

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from . import controllers
from . import moso_api

View File

@ -0,0 +1,24 @@
# controllers/main.py
from odoo import http
from odoo.http import request
class WebsiteEmbed(http.Controller):
@http.route('/moso', type='http', auth='public', website=True)
def homepage(self, **kw):
return request.render('website_genhd_embeb.moso_homepage_template')
@http.route('/moso/productlist', type='http', auth='public', website=True)
def productpage(self, **kw):
conditions = request.env["moso.condition"].search([])
types = request.env["moso.type"].search([])
categorys = request.env["moso.category"].search([])
products = request.env["moso.product"].search([],limit=1)
product_count = request.env['product.template'].search_count([])
return request.render('website_genhd_embeb.moso_productlist_template',{"conditions":conditions,"types":types,"categorys":categorys,"products":products,"product_count":product_count})
@http.route('/moso/product/<category_name>/', type='http', auth='public', website=True)
def productdetail(self,category_name):
category = request.env['moso.category'].sudo().search([('name', '=', category_name)], limit=1)
return request.render("website_genhd_embeb.moso_deltailpage_template",{'category':category})
@http.route('/moso/oder', type='http', auth='public', website=True)
def orderpage(self):
return request.render("website_genhd_embeb.moso_order_template")

View File

@ -0,0 +1,2 @@
from odoo import http
from odoo.http import request

View File

@ -0,0 +1,30 @@
<odoo>
<data>
<!--
<record id="object0" model="website_genhd_embeb.website_genhd_embeb">
<field name="name">Object 0</field>
<field name="value">0</field>
</record>
<record id="object1" model="website_genhd_embeb.website_genhd_embeb">
<field name="name">Object 1</field>
<field name="value">10</field>
</record>
<record id="object2" model="website_genhd_embeb.website_genhd_embeb">
<field name="name">Object 2</field>
<field name="value">20</field>
</record>
<record id="object3" model="website_genhd_embeb.website_genhd_embeb">
<field name="name">Object 3</field>
<field name="value">30</field>
</record>
<record id="object4" model="website_genhd_embeb.website_genhd_embeb">
<field name="name">Object 4</field>
<field name="value">40</field>
</record>
-->
</data>
</odoo>

View File

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from . import models
from . import moso_category,moso_condition,moso_type,moso_product

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# from odoo import models, fields, api
# class website_genhd_embeb(models.Model):
# _name = 'website_genhd_embeb.website_genhd_embeb'
# _description = 'website_genhd_embeb.website_genhd_embeb'
# name = fields.Char()
# value = fields.Integer()
# value2 = fields.Float(compute="_value_pc", store=True)
# description = fields.Text()
#
# @api.depends('value')
# def _value_pc(self):
# for record in self:
# record.value2 = float(record.value) / 100

View File

@ -0,0 +1,14 @@
from odoo import models, fields
class MosoCategory(models.Model):
_name = 'moso.category'
_description = "Interior Category"
_sql_constraints = [
('unique_name', 'UNIQUE(name)', 'Tên danh mục phải là duy nhất.'),
]
product_id = fields.Many2one('moso.product',string = "mẫu thiết kế")
name = fields.Char(string="Tên danh mục", required=True, unique=True)
image = fields.Binary(string="Ảnh danh mục", attachment=True)
description = fields.Text(string="Mô tả danh mục")
price = fields.Integer(string="giá bán",default=0)

View File

@ -0,0 +1,9 @@
from odoo import models,fields
class MosoCondition(models.Model):
_name = "moso.condition"
_description = "condition interior"
_sql_constraints = [
('unique_name', 'UNIQUE(name)', 'Tên điều kiện phải là duy nhất.'),
]
name = fields.Char(string="tên điều kiện")

View File

@ -0,0 +1,10 @@
from odoo import fields,models,api
class MosoProduct(models.Model):
_name = "moso.product"
_sql_constraints = [
('unique_name', 'UNIQUE(name)', 'Tên sản phẩm phải là duy nhất.'),
]
name = fields.Char(String = "Tên nội thât",unique=True,require = True)
condition_id = fields.Many2one('moso.condition',String ="Điều kiện")
type_id = fields.Many2one("moso.type",string="thể loại")

View File

@ -0,0 +1,9 @@
from odoo import models,fields,api
class MosoType(models.Model):
_name = 'moso.type'
_description = "interiort type"
_sql_constraints = [
('unique_name', 'UNIQUE(name)', 'Tên thiết kế phải là duy nhất.'),
]
name = fields.Char(string="name",require=True,unique=True)

View File

@ -0,0 +1,5 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_moso_category_user,access.moso.category,model_moso_category,base.group_user,1,1,1,1
access_moso_condition_user,access.moso.condition,model_moso_condition,base.group_user,1,1,1,1
access_moso_type_user,access.moso.type,model_moso_type,base.group_user,1,1,1,1
access_moso_product_user,access.moso.product,model_moso_product,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_moso_category_user access.moso.category model_moso_category base.group_user 1 1 1 1
3 access_moso_condition_user access.moso.condition model_moso_condition base.group_user 1 1 1 1
4 access_moso_type_user access.moso.type model_moso_type base.group_user 1 1 1 1
5 access_moso_product_user access.moso.product model_moso_product base.group_user 1 1 1 1

View File

@ -0,0 +1,8 @@
.o_list_view .moso_image_small img,
.o_form_view .moso_image_small img,
.o_content .moso_image_small img {
width: 100px !important;
height: 100px !important;
object-fit: cover;
border-radius: 6px;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,6 @@
/**
* Owl Carousel v2.3.4
* Copyright 2013-2018 David Deutsch
* Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
*/
.owl-carousel,.owl-carousel .owl-item{-webkit-tap-highlight-color:transparent;position:relative}.owl-carousel{display:none;width:100%;z-index:1}.owl-carousel .owl-stage{position:relative;-ms-touch-action:pan-Y;touch-action:manipulation;-moz-backface-visibility:hidden}.owl-carousel .owl-stage:after{content:".";display:block;clear:both;visibility:hidden;line-height:0;height:0}.owl-carousel .owl-stage-outer{position:relative;overflow:hidden;-webkit-transform:translate3d(0,0,0)}.owl-carousel .owl-item,.owl-carousel .owl-wrapper{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0)}.owl-carousel .owl-item{min-height:1px;float:left;-webkit-backface-visibility:hidden;-webkit-touch-callout:none}.owl-carousel .owl-item img{display:block;width:100%}.owl-carousel .owl-dots.disabled,.owl-carousel .owl-nav.disabled{display:none}.no-js .owl-carousel,.owl-carousel.owl-loaded{display:block}.owl-carousel .owl-dot,.owl-carousel .owl-nav .owl-next,.owl-carousel .owl-nav .owl-prev{cursor:pointer;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.owl-carousel .owl-nav button.owl-next,.owl-carousel .owl-nav button.owl-prev,.owl-carousel button.owl-dot{background:0 0;color:inherit;border:none;padding:0!important;font:inherit}.owl-carousel.owl-loading{opacity:0;display:block}.owl-carousel.owl-hidden{opacity:0}.owl-carousel.owl-refresh .owl-item{visibility:hidden}.owl-carousel.owl-drag .owl-item{-ms-touch-action:pan-y;touch-action:pan-y;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.owl-carousel.owl-grab{cursor:move;cursor:grab}.owl-carousel.owl-rtl{direction:rtl}.owl-carousel.owl-rtl .owl-item{float:right}.owl-carousel .animated{animation-duration:1s;animation-fill-mode:both}.owl-carousel .owl-animated-in{z-index:0}.owl-carousel .owl-animated-out{z-index:1}.owl-carousel .fadeOut{animation-name:fadeOut}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}.owl-height{transition:height .5s ease-in-out}.owl-carousel .owl-item .owl-lazy{opacity:0;transition:opacity .4s ease}.owl-carousel .owl-item .owl-lazy:not([src]),.owl-carousel .owl-item .owl-lazy[src^=""]{max-height:0}.owl-carousel .owl-item img.owl-lazy{transform-style:preserve-3d}.owl-carousel .owl-video-wrapper{position:relative;height:100%;background:#000}.owl-carousel .owl-video-play-icon{position:absolute;height:80px;width:80px;left:50%;top:50%;margin-left:-40px;margin-top:-40px;background:url(owl.video.play.png) no-repeat;cursor:pointer;z-index:1;-webkit-backface-visibility:hidden;transition:transform .1s ease}.owl-carousel .owl-video-play-icon:hover{-ms-transform:scale(1.3,1.3);transform:scale(1.3,1.3)}.owl-carousel .owl-video-playing .owl-video-play-icon,.owl-carousel .owl-video-playing .owl-video-tn{display:none}.owl-carousel .owl-video-tn{opacity:0;height:100%;background-position:center center;background-repeat:no-repeat;background-size:contain;transition:opacity .4s ease}.owl-carousel .owl-video-frame{position:relative;z-index:1;height:100%;width:100%}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,37 @@
//jquery-click-scroll
//by syamsul'isul' Arifin
// var sectionArray = [1, 2, 3, 4, 5];
// $.each(sectionArray, function(index, value){
// $(document).scroll(function(){
// var offsetSection = $('#' + 'section_' + value).offset().top - 70;
// var docScroll = $(document).scrollTop();
// var docScroll1 = docScroll + 1;
// if ( docScroll1 >= offsetSection ){
// $('.navbar-nav .nav-item .nav-link').removeClass('active');
// $('.navbar-nav .nav-item .nav-link:link').addClass('inactive');
// $('.navbar-nav .nav-item .nav-link').eq(index).addClass('active');
// $('.navbar-nav .nav-item .nav-link').eq(index).removeClass('inactive');
// }
// });
// $('.click-scroll').eq(index).click(function(e){
// var offsetClick = $('#' + 'section_' + value).offset().top - 70;
// e.preventDefault();
// $('html, body').animate({
// 'scrollTop':offsetClick
// }, 300)
// });
// });
// $(document).ready(function(){
// $('.navbar-nav .nav-item .nav-link:link').addClass('inactive');
// $('.navbar-nav .nav-item .nav-link').eq(0).addClass('active');
// $('.navbar-nav .nav-item .nav-link:link').eq(0).removeClass('inactive');
// });

View File

@ -0,0 +1,56 @@
(function ($) {
"use strict";
// HERO SLIDE
$('.hero-slide').backstretch([
"/website_genhd_embeb/static/image/slideshow/white-wall-living-room-have-sofa-decoration-3d-rendering.jpg",
"/website_genhd_embeb/static/image/slideshow/interior-wall-mockup-with-sofa-cabinet-living-room-with-empty-white-wall-background-3d-rendering.jpg",
"/website_genhd_embeb/static/image/slideshow/wood-sideboard-living-room-interior-with-copy-space.jpg"
], { duration: 2000, fade: 750 });
// REVIEWS CAROUSEL
$('.reviews-carousel').owlCarousel({
items: 3,
loop: true,
dots: false,
nav: true,
autoplay: true,
margin: 30,
responsive: {
0: {
items: 1
},
600: {
items: 2
},
1000: {
items: 3
}
}
})
// CUSTOM LINK
$('.smoothscroll').click(function () {
var el = $(this).attr('href');
var elWrapped = $(el);
var header_height = $('.navbar').height();
scrollToDiv(elWrapped, header_height);
return false;
function scrollToDiv(element, navheight) {
var offset = element.offset();
var offsetTop = offset.top;
var totalScroll = offsetTop - navheight;
$('body,html').animate({
scrollTop: totalScroll
}, 300);
}
});
})(window.jQuery);

View File

@ -0,0 +1,4 @@
/*! Backstretch - v2.0.4 - 2013-06-19
* http://srobbin.com/jquery-plugins/backstretch/
* Copyright (c) 2013 Scott Robbin; Licensed MIT */
(function(a,d,p){a.fn.backstretch=function(c,b){(c===p||0===c.length)&&a.error("No images were supplied for Backstretch");0===a(d).scrollTop()&&d.scrollTo(0,0);return this.each(function(){var d=a(this),g=d.data("backstretch");if(g){if("string"==typeof c&&"function"==typeof g[c]){g[c](b);return}b=a.extend(g.options,b);g.destroy(!0)}g=new q(this,c,b);d.data("backstretch",g)})};a.backstretch=function(c,b){return a("body").backstretch(c,b).data("backstretch")};a.expr[":"].backstretch=function(c){return a(c).data("backstretch")!==p};a.fn.backstretch.defaults={centeredX:!0,centeredY:!0,duration:5E3,fade:0};var r={left:0,top:0,overflow:"hidden",margin:0,padding:0,height:"400px",width:"100%",zIndex:-999999},s={position:"absolute",display:"none",margin:0,padding:0,border:"none",width:"auto",height:"400px",maxHeight:"none",maxWidth:"none",zIndex:-999999},q=function(c,b,e){this.options=a.extend({},a.fn.backstretch.defaults,e||{});this.images=a.isArray(b)?b:[b];a.each(this.images,function(){a("<img />")[0].src=this});this.isBody=c===document.body;this.$container=a(c);this.$root=this.isBody?l?a(d):a(document):this.$container;c=this.$container.children(".backstretch").first();this.$wrap=c.length?c:a('<div class="backstretch"></div>').css(r).appendTo(this.$container);this.isBody||(c=this.$container.css("position"),b=this.$container.css("zIndex"),this.$container.css({position:"static"===c?"relative":c,zIndex:"auto"===b?0:b,background:"none"}),this.$wrap.css({zIndex:-999998}));this.$wrap.css({position:this.isBody&&l?"fixed":"absolute"});this.index=0;this.show(this.index);a(d).on("resize.backstretch",a.proxy(this.resize,this)).on("orientationchange.backstretch",a.proxy(function(){this.isBody&&0===d.pageYOffset&&(d.scrollTo(0,1),this.resize())},this))};q.prototype={resize:function(){try{var a={left:0,top:0},b=this.isBody?this.$root.width():this.$root.innerWidth(),e=b,g=this.isBody?d.innerHeight?d.innerHeight:this.$root.height():this.$root.innerHeight(),j=e/this.$img.data("ratio"),f;j>=g?(f=(j-g)/2,this.options.centeredY&&(a.top="-"+f+"px")):(j=g,e=j*this.$img.data("ratio"),f=(e-b)/2,this.options.centeredX&&(a.left="-"+f+"px"));this.$wrap.css({width:b,height:g}).find("img:not(.deleteable)").css({width:e,height:j}).css(a)}catch(h){}return this},show:function(c){if(!(Math.abs(c)>this.images.length-1)){var b=this,e=b.$wrap.find("img").addClass("deleteable"),d={relatedTarget:b.$container[0]};b.$container.trigger(a.Event("backstretch.before",d),[b,c]);this.index=c;clearInterval(b.interval);b.$img=a("<img />").css(s).bind("load",function(f){var h=this.width||a(f.target).width();f=this.height||a(f.target).height();a(this).data("ratio",h/f);a(this).fadeIn(b.options.speed||b.options.fade,function(){e.remove();b.paused||b.cycle();a(["after","show"]).each(function(){b.$container.trigger(a.Event("backstretch."+this,d),[b,c])})});b.resize()}).appendTo(b.$wrap);b.$img.attr("src",b.images[c]);return b}},next:function(){return this.show(this.index<this.images.length-1?this.index+1:0)},prev:function(){return this.show(0===this.index?this.images.length-1:this.index-1)},pause:function(){this.paused=!0;return this},resume:function(){this.paused=!1;this.next();return this},cycle:function(){1<this.images.length&&(clearInterval(this.interval),this.interval=setInterval(a.proxy(function(){this.paused||this.next()},this),this.options.duration));return this},destroy:function(c){a(d).off("resize.backstretch orientationchange.backstretch");clearInterval(this.interval);c||this.$wrap.remove();this.$container.removeData("backstretch")}};var l,f=navigator.userAgent,m=navigator.platform,e=f.match(/AppleWebKit\/([0-9]+)/),e=!!e&&e[1],h=f.match(/Fennec\/([0-9]+)/),h=!!h&&h[1],n=f.match(/Opera Mobi\/([0-9]+)/),t=!!n&&n[1],k=f.match(/MSIE ([0-9]+)/),k=!!k&&k[1];l=!((-1<m.indexOf("iPhone")||-1<m.indexOf("iPad")||-1<m.indexOf("iPod"))&&e&&534>e||d.operamini&&"[object OperaMini]"==={}.toString.call(d.operamini)||n&&7458>t||-1<f.indexOf("Android")&&e&&533>e||h&&6>h||"palmGetResource"in d&&e&&534>e||-1<f.indexOf("MeeGo")&&-1<f.indexOf("NokiaBrowser/8.5.0")||k&&6>=k)})(jQuery,window);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More