How to receive payment in Euro (using Stripe API) in Python - stripe-payments

I want to receive payment in euro but receiving in usd.
I made a website for France country, we need to accept money in euro currency but getting in usd by Stripe using django
Here is the code for stripe
if request.method == "POST":
payment_type = request.POST["payment_type"]
amount_dues = request.POST["amount_dues"]
amount1 = request.POST["amount"]
amount2 = amount1.split("€")
amount = float(amount2[0])
email1 = request.POST["email"]
paid_amount = amount
customer = stripe.Customer.create(
email=request.POST["email"],
name=request.POST["nickname"],
source=request.POST["stripeToken"],
address={
"city": "kfhdksh",
"country": "France",
"line1": "566d ihflks",
"postal_code": "77140",
"state": "lfjkshkjsk",
},
)
int_amount = amount * 100
int_amount = int(int_amount)
charge = stripe.Charge.create(
customer=customer,
amount=int_amount,
currency="eur",
description="charges for ride of Customer Id = "
+ str(myid),
)
return redirect(reverse("success", args=[amount]))
Please help in getting currency in euro
What can I change in code or in stripe setting

Related

how to change SL/TP with CCXT (python) on Binance Futures

How can I change the take profit or stop loss of an order already created via ccxt python in Binance futures?
I would like an already created order to be able to change the stop loss, as if I did it from the binance web cli, there is some way, I create my order like this
exchange.create_order(symbol=par, type='limit', side=side, price = precio, amount= monto, params={})
When detecting a certain pattern I would like to update the SL and TP, it's possible?
I have not found information in the ccxt wiki
There is an edit_order function that you may want to try.
import ccxt
exchange = ccxt.binanceusdm()
exchange.apiKey = 'YOUR_API_KEY'
exchange.secret = 'YOUR_API_SECRET'
symbol = 'BTC/USDT'
order_id = 'ORDER_ID'
order_type = 'limit'
side = 'buy'
amount = 0.001
price = 16000
stop_loss = 15000
take_profit = 17000
exchange.edit_order(order_id, symbol, order_type, side, amount, price, {'stopLossPrice': stop_loss, 'takeProfitPrice': take_profit})

When working with the Stripe API, is it better to sort each request or store locally and perform queries?

This is my first post, I've been lurking for a while.
Some context to my question;
I'm working with the Stripe API to pull transaction data and match these with booking numbers from another API source. (property reservations --> funds received for reconciliation)
I started by just making calls to the API and sorting the data in place using python 3, however it started to get very complicated and I thought I should persist the data in a mongodb stored on localhost. I began to do this, however I decided that storing the sorted data was still just as complicated and the request times were getting quite long, I thought, maybe I should pull all the stripe data and store it locally and then query whatever I needed.
So here I am, with a bunch of code I've written for both and still not alot of progress. I'm a bit lost with the next move. I feel like I should probably pick a path and stick with it. I'm a little unsure what is the "best practise" when working with API's, usually I would turn to YouTube, but I haven't been able to find a video which covers this specific scenario. The amount of data being pulled from the API would be around 100kb per request.
Here is the original code which would grab each query. Recently I've learnt I can use the expand method (I think this is what it's called) so I don't need to dig down so many levels in my for loop.
The goal was to get just the metadata which contains the booking reference numbers that can then be match against a response from my property management systems API. My code is a bit embarrassing, I've kinda just learnt it over the last little while in my downtime from work.
import csv
import datetime
import os
import pymongo
import stripe
"""
We need to find a Valid reservation_ref or reservation_id in the booking.com Metadata. Then we need to match this to a property ID from our list of properties in the book file.
"""
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
stripe_payouts = mydb["stripe_payouts"]
stripe.api_key = "sk_live_thisismyprivatekey"
r = stripe.Payout.list(limit=4)
payouts = []
for data in r['data']:
if data['status'] == 'paid':
p_id = data['id']
amount = data['amount']
meta = []
txn = stripe.BalanceTransaction.list(payout=p_id)
amount_str = str(amount)
amount_dollar = str(amount / 100)
txn_len = len(txn['data'])
for x in range(txn_len):
if x != 0:
charge = (txn['data'][x]['source'])
if charge.startswith("ch_"):
meta_req = stripe.Charge.retrieve(charge)
meta = list(meta_req['metadata'])
elif charge.startswith("re_"):
meta_req = stripe.Refund.retrieve(charge)
meta = list(meta_req['metadata'])
if stripe_payouts.find({"_id": p_id}).count() == 0:
payouts.append(
{
"_id": str(p_id),
"payout": str(p_id),
"transactions": txn['data'],
"metadata": {
charge: [meta]
}
}
)
# TODO: Add error exception to check for po id already in the database.
if len(payouts) != 0:
x = stripe_payouts.insert_many(payouts)
print("Inserted into Database ", len(x.inserted_ids), x.inserted_ids)
else:
print("No entries made")
"_id": str(p_id),
"payout": str(p_id),
"transactions": txn['data'],
"metadata": {
charge: [meta]
This last section doesn't work properly, this is kinda where I stopped and starting calling all the data and storing it in mongodb locally.
I appreciate if you've read this wall of text this far.
Thanks
EDIT:
I'm unsure what the best practise is for adding additional information, but I've messed with the code below per the answer given. I'm now getting a "Key error" when trying to insert the entries into the database. I feel like It's duplicating keys somehow.
payouts = []
def add_metadata(payout_id, transaction_type):
transactions = stripe.BalanceTransaction.list(payout=payout_id, type=transaction_type, expand=['data.source'])
for transaction in transactions.auto_paging_iter():
meta = [transaction.source.metadata]
if stripe_payouts.Collection.count_documents({"_id": payout_id}) == 0:
payouts.append(
{
transaction.id: transaction
}
)
for data in r['data']:
p_id = data['id']
add_metadata(p_id, 'charge')
add_metadata(p_id, 'refund')
# TODO: Add error exception to check for po id already in the database.
if len(payouts) != 0:
x = stripe_payouts.insert_many(payouts)
#print(payouts)
print("Inserted into Database ", len(x.inserted_ids), x.inserted_ids)
else:
print("No entries made")```
To answer your high level question. If you're frequently accessing the same data and that data isn't changing much then it can make sense to try to keep your local copy of the data in sync and make your frequent queries against your local data.
No need to be embarrassed by your code :) we've all been new at something at some point.
Looking at your code I noticed a few things:
Rather than fetch all payouts, then use an if statement to skip all except paid, instead you can pass another filter to only query those paid payouts.
r = stripe.Payout.list(limit=4, status='paid')
You mentioned the expand [B] feature of the API, but didn't use it so I wanted to share how you can do that here with an example. In this case, you're making 1 API call to get the list of payouts, then 1 API call per payout to get the transactions, then 1 API call per charge or refund to get the metadata for charges or metadata for refunds. This results in 1 * (n payouts) * (m charges or refunds) which is a pretty big number. To cut this down, let's pass expand=['data.source'] when fetching transactions which will include all of the metadata about the charge or refund along with the transaction.
transactions = stripe.BalanceTransaction.list(payout=p_id, expand=['data.source'])
Fetching the BalanceTransaction list like this will only work as long as your results fit on one "page" of results. The API returns paginated [A] results, so if you have more than 10 transactions per payout, this will miss some. Instead, you can use an auto-pagination feature of the stripe-python library to iterate over all results from the BalanceTransaction list.
for transaction in transactions.auto_paging_iter():
I'm not quite sure why we're skipping over index 0 with if x != 0: so that may need to be addressed elsewhere :D
I didn't see how or where amount_str or amount_dollar was actually used.
Rather than determining the type of the object by checking the ID prefix like ch_ or re_ you'll want to use the type attribute. Again in this case, it's better to filter by type so that you only get exactly the data you need from the API:
transactions = stripe.BalanceTransaction.list(payout=p_id, type='charge', expand=['data.source'])
I'm unable to test because I lack the same database that you have, but wanted to share a refactoring of your code that you may consider.
r = stripe.Payout.list(limit=4, status='paid')
payouts = []
for data in r['data']:
p_id = data['id']
amount = data['amount']
meta = []
amount_str = str(amount)
amount_dollar = str(amount / 100)
transactions = stripe.BalanceTransaction.list(payout=p_id, type='charge', expand=['data.source'])
for transaction in transactions.auto_paging_iter():
meta = list(transaction.source.metadata)
if stripe_payouts.find({"_id": p_id}).count() == 0:
payouts.append(
{
"_id": str(p_id),
"payout": str(p_id),
"transactions": transactions,
"metadata": {
charge: [meta]
}
}
)
transactions = stripe.BalanceTransaction.list(payout=p_id, type='refund', expand=['data.source'])
for transaction in transactions.auto_paging_iter():
meta = list(transaction.source.metadata)
if stripe_payouts.find({"_id": p_id}).count() == 0:
payouts.append(
{
"_id": str(p_id),
"payout": str(p_id),
"transactions": transactions,
"metadata": {
charge: [meta]
}
}
)
# TODO: Add error exception to check for po id already in the database.
if len(payouts) != 0:
x = stripe_payouts.insert_many(payouts)
print("Inserted into Database ", len(x.inserted_ids), x.inserted_ids)
else:
print("No entries made")
Here's a further refactoring using functions defined to encapsulate just the bit adding to the database:
r = stripe.Payout.list(limit=4, status='paid')
payouts = []
def add_metadata(payout_id, transaction_type):
transactions = stripe.BalanceTransaction.list(payout=payout_id, type=transaction_tyep, expand=['data.source'])
for transaction in transactions.auto_paging_iter():
meta = list(transaction.source.metadata)
if stripe_payouts.find({"_id": payout_id}).count() == 0:
payouts.append(
{
"_id": str(payout_id),
"payout": str(payout_id),
"transactions": transactions,
"metadata": {
charge: [meta]
}
}
)
for data in r['data']:
p_id = data['id']
add_metadata('charge')
add_metadata('refund')
# TODO: Add error exception to check for po id already in the database.
if len(payouts) != 0:
x = stripe_payouts.insert_many(payouts)
print("Inserted into Database ", len(x.inserted_ids), x.inserted_ids)
else:
print("No entries made")
[A] https://stripe.com/docs/api/pagination
[B] https://stripe.com/docs/api/expanding_objects

How to limit the approve action only for the manager of team

I'm using odoo11 and i have installed a custom module to calculate the overtime, i've many team leaders, each team leader has a number of employee.
I want to limit the approve action for the manager in a way every manager approve request of his own employees only.
I have override the approve action to verify if the person who's gone approve is his manager or not but always it allows any manager to approve all the requests. Here is code :
overtime.py
class BtHrOvertime(models.Model):
_name = "bt.hr.overtime"
_description = "Bt Hr Overtime"
_rec_name = 'employee_id'
_order = 'id desc'
employee_id = fields.Many2one('hr.employee', string="Employee")
manager_id = fields.Many2one('hr.employee', string='Manager')
start_date = fields.Datetime('Date check in')
end_date = fields.Datetime('Date check out')
overtime_hours = fields.Float('Overtime Hours')
notes = fields.Text(string='Notes')
state = fields.Selection([('draft', 'Draft'), ('confirm', 'Waiting for Approval'), ('refuse', 'Refused'),
('validate', 'Approved'), ('cancel', 'Cancelled')], default='draft', copy=False)
attendance_id = fields.Many2one('hr.attendance', string='Attendance')
user_id = fields.Many2one('res.users', string='User', related='employee_id.user_id', related_sudo=True,
compute_sudo=True, store=True, default=lambda self: self.env.uid, readonly=True)
parent_id = fields.Many2one('bt.hr.overtime', string='Parent', copy=False)
#api.multi
def action_approve(self):
if (self.employee_id.parent_id.user_id.id != uid):
raise exceptions.UserError(_('You cannot approve.'))
elif self.attendance_id.check_in and self.attendance_id.check_out:
start_date = datetime.datetime.strptime(self.attendance_id.check_in, DEFAULT_SERVER_DATETIME_FORMAT)
end_date = datetime.datetime.strptime(self.attendance_id.check_out, DEFAULT_SERVER_DATETIME_FORMAT)
difference = end_date - start_date
hour_diff = str(difference).split(':')[0]
min_diff = str(difference).split(':')[1]
tot_diff = hour_diff + '.' + min_diff
actual_working_hours = float(tot_diff)
for record in self:
if actual_working_hours > 9:
record.overtime_hours = actual_working_hours - 9
record.start_date = record.attendance_id.check_in
record.end_date = record.attendance_id.check_out
else:
record.overtime_hours = 0
record.start_date = record.attendance_id.check_in
record.end_date = record.attendance_id.check_out
return self.write({'state': 'validate'})
Please use the below code or checking:
if (self.employee_id.parent_id.user_id.id != self.env.user.id):
raise exceptions.UserError(_('You cannot approve.'))
I think that employee_id.parent_id is the manager of the employee. Also please be informed that you can create a new user group
<record id="group_is_manager" model="res.groups">
<field name="name">Is a manager?</field>
</record>
For the Manager users you can check this group and give this group for approve button
<button name="" string="" type="" groups="module_name.group_is_manager"/>
Hence, the button will be visible to those users who have this group.

Finding multiple accounts under the same name for Python bank system

In my bank system I have a set of customer accounts but for one name Adam Smith he has two accounts:
def load_bank_data(self):
# the customers in the bank system
account_no = 1234
customer_1 = CustomerAccount("Adam", "Smith", 14, "Wilcot Street", "Bath", "B5 5RT", account_no, "Current", 2500.00)
self.accounts_list.append(customer_1)
account_no += 5678
customer_2 = CustomerAccount("David", "White", 60, "Holburn Viaduct", "London", "EC1A 2FD", account_no, "Savings", 3200.00)
self.accounts_list.append(customer_2)
account_no += 3456
customer_3 = CustomerAccount("Alice", "Churchil", 55, "Cardigan Street", "Birmingham", "B4 7BD", account_no, "Current", 18000.00)
self.accounts_list.append(customer_3)
account_no += 6789
customer_4 = CustomerAccount("Ali", "Abdallah", 44, "Churchill Way West", "Basingstoke", "RG21 6YR", account_no, "Savings", 40.00)
self.accounts_list.append(customer_4)
account_no += 1987
customer_5 = CustomerAccount("Adam", "Smith", 44, "Churchill Way West", "Basingstoke", "RG21 6YR", account_no, "Savings", 5000.00)
self.accounts_list.append(customer_5)
I created a function so when many customer accounts under the same first and last name have been found, it should add all those bank account balances together and print out the final total. (The input is where I type the customer to find multiple accounts for:
def sum_of_all_money(self):
try:
find_customer = input("Enter the surname of the customer to find total sum of money for: ")
for find_customer in self.accounts_list:
find_customer = find_customer.get_balance() + find_customer.get_balance()
print(find_customer)
except SyntaxError as e:
print(e)
This is only just finding one Adam Smith account at the bottom as customer 5 but it doesn't detect the other Adam Smith account as customer 1 and it just adds customer 5 twice giving me an output of 1000.00 which isn't right, what am I doing wrong?
Your code has some flaws, currently it will only loop over your list and always overwrite find_customer with the current balance of the customer * 2.
You need to filter for the right name which was input, try it like this:
try:
find_customer = input("Enter the surname of the customer to find total sum of money for: ")
find_customer_balance = 0
for customer in self.accounts_list:
if customer.get_surname() == find_customer:
find_customer_balance += customer.get_balance()
print(find_customer)
print(find_customer_balance)
except SyntaxError as e:
print(e)

How to call a function every interval time Odoo 11

i know we can create automatic action using cron in odoo
but I want something a different
in the mass mailing of odoo i want to add a repetion option of mail mass mailings
Example in the Form view_mail_mass_mailing_form > Options page
I added a repetition selection field,
I added this because I want each mass mail alone
class MailMassMailing(models.Model):
_inherit = 'mail.mass_mailing'
recurrence_mail = fields.Selection([
('daily', 'Day'),
('weekly', 'Weeks'),
('monthly', 'Months'),
], string='Recurring')
I want this mass mailng to send each (days or weeks or months)
how to call a function with interval date,
how to call a function every (days or weeks or months)
The sending of this mass mailing is revived from the date of creation
Just extend Mass Mailing model with a new date field and implement a model method to use for a daily running ir.cron.
from odoo import api, fields, models
class MailMassMailing(models.Model):
_inherit = 'mail.mass_mailing'
recurrence_mail = fields.Selection([
('daily', 'Day'),
('weekly', 'Weeks'),
('monthly', 'Months'),
], string='Recurring')
last_sent_on = fields.Date()
#api.model
def run_send_recurring(self):
""" Resend mass mailing with recurring interval"""
domain = [('recurrence_mail', '!=', False)]
# TODO monthly should be solved in another way, but that
# is not needed for this example
deltas = {'daily': 1, 'weekly': 7, 'monthly': 30}
today = fields.Date.today()
for mass_mail in self.search(domain):
# never sent? go send it
if not mass_mail.last_sent_on:
# send the way you want
# or get delta between today and last_sent_on
last_dt = fields.Date.from_string(mass_mail.last_sent_on)
if (today - last_dt).days >= deltas[mass_mail.recurrence_mail]:
# send the way you want
Thank you #CZoellner for your help
I found the solution with your idea
# Solution ############### .py
#api.model
def run_send_recurring(self):
""" Resend mass mailing with recurring interval"""
date_format = '%Y-%m-%d'
domain = [('recurrence_mail', '!=', False),('state','=','done')]
deltas = {'daily': 1, 'weekly': 7, 'monthly': 30}
logger.info("______deltas________: %s ",deltas)
today = fields.Date.today()
logger.info("______today________: %s ",today)
for mass_mail in self.search(domain):
logger.info("______mass_mail________: %s ",mass_mail)
# never sent? go send it
if not mass_mail.last_sent_on:
self.put_in_queue()
joining_date = mass_mail.last_sent_on
current_date = (datetime.today()).strftime(date_format)
print('joining_date',joining_date)
d1 = datetime.strptime(joining_date, date_format).date()
logger.info("______1 day________: %s ",d1)
d2 = datetime.strptime(current_date, date_format).date()
logger.info("______2 day________: %s ",d2)
logger.info("______deltas[mass_mail.recurrence_mail]________: %s ",deltas[mass_mail.recurrence_mail])
r = relativedelta(d1,d2)
logger.info("______r day________: %s ",r.days)
if (r ,'>=' , deltas[mass_mail.recurrence_mail]):
mass_mail.put_in_queue()

Resources