Skip to content

Commit

Permalink
Merge pull request #17 from umithan-guldemir/16.0-mig-partner_org_chart
Browse files Browse the repository at this point in the history
16.0 mig partner org chart
  • Loading branch information
yibudak authored Dec 27, 2024
2 parents 7911ebd + 2c19023 commit e2ce3ea
Show file tree
Hide file tree
Showing 52 changed files with 3,727 additions and 255 deletions.
15 changes: 15 additions & 0 deletions account_statement_import_online_finekra/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
===================================
Online Bank Statements: Finekra
===================================


### Bu modül ne işe yarar?:

Bankalardan anlık olarak tüm hesap bilgileriniz alınır. Tüm bankalarınızdaki hesap bakiyelerinize ve hareketlerinize tek bir ekrandan ulaşabilirsiniz.
Bu modül Odoo ile Finekra API'sini bağlayarak banka ekstrelerinizi otomatik bir şekilde aktarılmasına yarar.

Ayrıca, banka havalesi ödemelerin açıklamasını otomatik olarak okuyarak, ödeme kaydetme işlemini gerçekleştirir.


### Gereken Modüller:
* account__statement_import_online
4 changes: 4 additions & 0 deletions account_statement_import_online_finekra/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright 2022 Yiğit Budak (https://github.com/yibudak)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import models
21 changes: 21 additions & 0 deletions account_statement_import_online_finekra/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2022 Yiğit Budak (https://github.com/yibudak)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Online Bank Statements: Finekra",
"version": "12.0.1.1.0",
"category": "Account",
"website": "https://github.com/odoo-turkey/integration",
"author": "Yiğit Budak, Odoo Turkey Localization Group",
"license": "AGPL-3",
"installable": True,
"depends": [
"account_statement_import_online",
"sale",
# "sale_confirm_payment", # TODO: this module should be migrated also.
],
"data": [
"view/online_bank_statement_provider.xml",
"view/account_journal.xml",
"view/account_bank_statement_line_view.xml",
],
}
6 changes: 6 additions & 0 deletions account_statement_import_online_finekra/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright 2022 Yiğit Budak (https://github.com/yibudak)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import online_bank_statement_provider_finekra
from . import account_journal
from . import account_bank_statement_line
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Copyright 2024 Yiğit Budak (https://github.com/yibudak)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
from odoo import models, api, fields
from odoo.tools import float_compare
import re


class AccountBankStatementLine(models.Model):
_inherit = "account.bank.statement.line"

order_ids = fields.Many2many(
"sale.order",
"sale_order_bank_statement_line_rel",
"statement_line_id",
"order_id",
string="Sale Orders",
)

@api.model
def create(self, vals):
"""
Inherited to automatically bind orders to statement line
:param vals:
:return:
"""
res = super(AccountBankStatementLine, self).create(vals)
order_ref_pattern = r"\b[A-Za-z]{2}\d{6,7}\b"
matched_refs = re.findall(order_ref_pattern, res.name)
if matched_refs:
# Todo: this method could be multi as well
orders = self.env["sale.order"].search(
[
("name", "in", matched_refs),
("state", "in", ["draft", "sent"]),
]
)
if len(orders) != 1:
return res

if float_compare(orders.amount_total, res.amount, 2) != 0:
return res

commercial_partner = orders.mapped("partner_id.commercial_partner_id")

# We can't create payment for multiple partners
if len(commercial_partner) > 1:
return res

# Only work on positive amounts
if res.amount < 0:
return res

data = [
{
"counterpart_aml_dicts": [],
"new_aml_dicts": [
{
"account_id": commercial_partner.property_account_receivable_id.id,
"analytic_tag_ids": [[6, None, []]],
"credit": res.amount,
"company_id": res.company_id.id,
# we are working with credit, so residual amount is negative
"amount_residual": -res.amount,
"debit": 0,
"name": res.name,
}
],
"partner_id": commercial_partner.id,
"payment_aml_ids": [],
}
]
self.env["account.reconciliation.widget"].process_bank_statement_line(
st_line_ids=[res.id], data=data
)

# Bind orders to statement line
res.order_ids = [(6, 0, orders.ids)]

payment_id = res.mapped("journal_entry_ids.payment_id")
if payment_id:
# Bind the payment to orders and Confirm orders
for order in orders:
order.write(
{
"payment_status": "done",
"payment_ids": [(6, 0, payment_id.ids)],
"payment_term_id": 23, # Banka havalesi
},
)
order.with_context(bypass_risk=True).action_confirm()
return res
10 changes: 10 additions & 0 deletions account_statement_import_online_finekra/models/account_journal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copyright 2022 Yiğit Budak (https://github.com/yibudak)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from odoo import models, fields


class AccountJournal(models.Model):
_inherit = "account.journal"

finekra_account_id = fields.Char("Finekra Account ID")
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# Copyright 2022 Yiğit Budak (https://github.com/yibudak)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import requests
from datetime import datetime, timedelta

import uuid

from odoo import api, fields, models, _
from odoo.exceptions import UserError

FINEKRA_ENDPOINT = "https://test-api.finekra.com"


class OnlineBankStatementProviderFinekra(models.Model):
_inherit = "online.bank.statement.provider"

finekra_email = fields.Char("Finekra App Key")
finekra_password = fields.Char("Finekra App Secret")
finekra_tenant_code = fields.Text("Finekra Tenant code")
finekra_jwt_token = fields.Text("JWT Token", readonly=True)
finekra_token_interval = fields.Datetime(
"Token Interval", default="2000-01-01 00:00:00"
)

@api.model
def _get_available_services(self):
return super()._get_available_services() + [
("finekra", "Finekra"),
]

def _obtain_statement_data(self, date_since, date_until):
self.ensure_one()
if self.service != "finekra":
return super()._obtain_statement_data(
date_since,
date_until,
)
return self._finekra_obtain_statement_data(date_since, date_until)

##########
# finekra #
##########

def _finekra_get_request(self, endpoint, data=None):
"""
Sends GET request to finekra Endpoint
:param endpoint:
:param data:
:return:
"""
headers = {
"Content-Type": "application/json;odata.metadata=minimal;odata.streaming=true",
"Authorization": "Bearer %s" % self.finekra_jwt_token,
}
response = requests.get(endpoint, params=data, headers=headers)


if response.status_code == 200:
return response.json()
else:
for i in range(len(response.text)):
print(i)
print(response.text)
raise UserError(_(response))

def _finekra_post_request(self, endpoint, data=None):
"""
Sends POST request to finekra Endpoint
:param endpoint:
:param data:
:return:
"""
headers = {
"Content-Type": "application/json;odata.metadata=minimal;odata.streaming=true",
"Authorization": "Bearer %s" % self.finekra_jwt_token,
}
response = requests.post(endpoint, json=data, headers=headers)

if response.status_code == 200:
return response.json()
else:
raise UserError(_("Finekra API Error."))

def _finekra_get_auth(self):
self.ensure_one()
if self.finekra_email and self.finekra_password and self.finekra_tenant_code:

if (
not self.finekra_jwt_token
or self.finekra_token_interval < datetime.now()
):
vals = {
"email": self.finekra_email,
"password": self.finekra_password,
"tenantCode": self.finekra_tenant_code,
"screenOption": 0,
}
resp = requests.post(
"%s/api/Auth/DealerLogin" % FINEKRA_ENDPOINT, json=vals
).json()
if resp.get("success"):
self.write(
{
"finekra_jwt_token": resp["data"].get("token"),
"finekra_token_interval": datetime.now()
+ timedelta(days=1),
}
)
else:
raise UserError(_("Please fill email, password and tenant code."))

def _finekra_get_transaction(self, account_id, date_since, date_until):
page_url = "%s/api/AccountTransaction" % FINEKRA_ENDPOINT

vals = {
"$filter": "TenantAccountId eq %s and"
" date(TransactionDateValue) le %s and"
" date(TransactionDateValue) ge %s"
% (
account_id,
date_until.strftime("%Y-%m-%d"),
date_since.strftime("%Y-%m-%d"),
)
}

data = self._finekra_get_request(endpoint=page_url, data=vals)
if data.get("value"):
return data.get("value")
else:
return []

def _finekra_date_from_string(self, date_str):
"""Finekra dates are GMT+3, so we don't need to convert them to UTC"""
dt = datetime.strptime(date_str, "%d.%m.%Y %H:%M")
return dt

def _finekra_obtain_statement_data(self, date_since, date_until):
# currency_dict = {x.name: x.id for x in self.env['res.currency'].search([('active', '=', True)])}
self.ensure_one()
self._finekra_get_auth()
journal = self.journal_id
account_id = journal.finekra_account_id

if not account_id:
raise UserError(
_("finekra : wrong configuration, unknown account %s")
% journal.bank_account_id.acc_number
)
transaction_lines = self._finekra_get_transaction(
account_id, date_since, date_until
)
new_transactions = []
# transcationun currency si, unique import idsi, amount'u
sequence = 0
for transaction in transaction_lines:
# currency = transaction.get('currency')
sequence += 1
date = self._finekra_date_from_string(transaction.get("transactionDate"))
vals_line = {
"sequence": sequence,
"date": date,
"name": transaction.get("description", journal.name),
"unique_import_id": transaction["id"],
"amount": transaction["amountForExcel"],
}
# if currency != 'TRY':
# vals_line.update({
# 'currency_id': currency_dict.get(currency),
# })

new_transactions.append(vals_line)
if new_transactions:
return new_transactions, {}
return
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record model="ir.ui.view" id="bank_statement_line_tree_finekra">
<field name="name">account.bank.statement.line.tree.finekra</field>
<field name="model">account.bank.statement.line</field>
<field name="inherit_id" ref="account_statement_base.account_bank_statement_line_tree"/>
<field name="arch" type="xml">
<field name="ref" position="after">
<field name="order_ids"/>
</field>
</field>
</record>
</odoo>
16 changes: 16 additions & 0 deletions account_statement_import_online_finekra/view/account_journal.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record model="ir.ui.view" id="view_account_journal_form_finekra">
<field name="name">account.journal.form</field>
<field name="model">account.journal</field>
<field name="inherit_id" ref="account.view_account_journal_form"/>
<field name="arch" type="xml">
<group name="online_bank_statements" position="inside">
<field name="finekra_account_id"/>
</group>
</field>
</record>


</odoo>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record model="ir.ui.view" id="online_bank_statement_provider_form_finekra">
<field name="name">online.bank.statement.provider.form.finekra</field>
<field name="model">online.bank.statement.provider</field>
<field
name="inherit_id"
ref="account_statement_import_online.online_bank_statement_provider_form"
/>
<field name="arch" type="xml">
<!-- < page idi groupa çevirdim -->
<xpath expr="//group[@name='configuration']" position="inside">
<group name="finekra" attrs="{'invisible':[('service','!=','finekra')]}">
<field name="finekra_email"/>
<field name="finekra_password"/>
<field name="finekra_tenant_code"/>
</group>
</xpath>
</field>
</record>
</odoo>
1 change: 1 addition & 0 deletions altinkaya_crm/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
Loading

0 comments on commit e2ce3ea

Please sign in to comment.