I am currently working on a delivery app. Basically, what I am trying to achieve here is to have a counter that display out any potential duplicated jobs that the customer might have accidently double entered.
The criteria to be considered as a duplicated job is as such:
- Has to have same delivery_address and same pickup_date.
This is my postgresql tables:
class Order(models.Model):
id_order = models.AutoField(primary_key=True)
class OrderDelivery(models.Model):
order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True, blank=True)
delivery_address = models.TextField()
class OrderPickup(models.Model):
order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True, blank=True)
pickup_date = models.DateField(blank=True, null=True)
This is what I have came up with so far:
def dashboard_duplicated_job(orders, month):
# This function finds for jobs that has
# (1) exact pickup_date
# (2) exact delivery address
# and mark it as duplicated job.
# Find current month, if not take current year
now = timezone.localtime(timezone.now())
month = "12" if month and int(month) == 0 else month
if month == 12 or month == '12':
now = timezone.localtime(timezone.now())
last_month = now.today() + relativedelta(months=-1)
start_date = last_month.replace(day=1).strftime('%Y-%m-%d')
year = last_month.replace(day=1).strftime('%Y')
month = last_month.replace(day=1).strftime('%m')
last_day = calendar.monthrange(int(year), int(month))[1]
string_start = str(year) + "-" + str(month) + "-01"
string_end = str(year) + "-" + str(month) + "-" + str(last_day)
start_date = datetime.strptime(string_start + " 00:00:00", "%Y-%m-%d %H:%M:%S")
end_date = datetime.strptime(string_end + " 23:59:59", "%Y-%m-%d %H:%M:%S")
else:
year = now.year
last = calendar.monthrange(year, int(month))[1]
string_start = str(year) + "-" + str(month) + "-01"
string_end = str(year) + "-" + str(month) + "-" + str(last)
start_date = datetime.strptime(string_start + " 00:00:00", "%Y-%m-%d %H:%M:%S")
end_date = datetime.strptime(string_end + " 23:59:59", "%Y-%m-%d %H:%M:%S")
# Filter pickup_date of Orderpickup to display only orders related to current month
opu = OrderPickup.objects.filter(
order_id__in=orders,
pickup_date__range=(start_date, end_date)
).values(
'order_id',
'pickup_date',
)
# Filter OrderDelivery based on pickup_date range
ods = OrderDelivery.objects.filter(
order_id__in=opu.values('order_id')
).values(
'order_id',
'delivery_address',
# 'reference_no'
)
# Find duplicated delivery_address
dup_ods = ods.values(
'delivery_address'
).annotate(
duplicated_delivery_address=Count('delivery_address')
).filter(
duplicated_delivery_address__gt=1
)
# Extract the IDs of the duplicated delivery_address from dup_ods
dup_ods_id = ods.filter(
delivery_address__in=[item['delivery_address'] for item in dup_ods]
).values(
'order_id'
)
# Find duplicated pickup_date based on duplicated_address <not working as intended>
dup_opu = opu.filter(
order_id__in=dup_ods_id
).values(
'pickup_date'
).annotate(
duplicated_pickup_date=Count('pickup_date')
).filter(
duplicated_pickup_date__gt=1
)
dup_opu_id = opu.filter(
pickup_date__in=[item['pickup_date'] for item in dup_opu]
).order_by()
orders = orders.filter(id_order__in=dup_opu_id)
return orders
Based on what I have came up with, I am having situation where orders that has same delivery_address but different pickup_date is showing up.
example (correct): | delivery_address | pickup_date| | -------- | -------------- | | here | 08-03-2022 | | here | 08-03-2022 | | there| 09-03-2022 | | there | 09-03-2022 |
example (incorrect, currently displaying): | delivery_address | pickup_date| | -------- | -------------- | | here | 08-03-2022 | | here | 08-03-2022 | | here | 09-03-2022 | | there| 09-03-2022 | | there | 09-03-2022 |
Please advise thank you.
UPDATE
I have managed to solve my problem. Below is my solution:
dup_job = orders.filter(
orderpickup__pickup_date__range=(start_date, end_date)
).values(
'id_order',
'orderdelivery__delivery_address',
'orderpickup__pickup_date'
).annotate(
duplicated=Count('orderdelivery__delivery_address')
).filter(
duplicated__gt=1
)