Beispiel #1
0
 def setUp(self):
     p1 = Product.get_by_code(TEST_DOMAIN, 'mc')
     p2 = Product.get_by_code(TEST_DOMAIN, 'lf')
     p3 = Product.get_by_code(TEST_DOMAIN, 'mg')
     self._create_stock_state(p1, 5)
     self._create_stock_state(p2, 10)
     self._create_stock_state(p3, 5)
Beispiel #2
0
    def delete(self):
        # you cannot delete the default program
        if self.default:
            raise Exception(_('You cannot delete the default program'))

        default = Program.default_for_domain(self.domain)

        products = Product.by_program_id(
            self.domain,
            self._id,
            wrap=False
        )
        to_save = []

        for product in products:
            product['program_id'] = default._id
            to_save.append(product)

            # break up saving in case there are many products
            if to_save > 500:
                Product.get_db().bulk_save(to_save)
                to_save = []

        Product.get_db().bulk_save(to_save)

        # bulk update sqlproducts
        SQLProduct.objects.filter(program_id=self._id).update(program_id=default._id)

        return super(Program, self).delete()
    def _create_data(self, domain_name, i):
        product = Product(domain=domain_name, name='test-{}'.format(i))
        product.save()

        location = Location(
            domain=domain_name,
            site_code='testcode-{}'.format(i),
            name='test-{}'.format(i),
            location_type='facility'
        )
        location.save()
        SupplyPointCase.create_from_location(domain_name, location)
        report = StockReport.objects.create(
            type='balance',
            domain=domain_name,
            form_id='fake',
            date=datetime.utcnow()
        )

        StockTransaction.objects.create(
            report=report,
            product_id=product.get_id,
            sql_product=SQLProduct.objects.get(product_id=product.get_id),
            section_id='stock',
            type='stockonhand',
            case_id=location.linked_supply_point().get_id,
            stock_on_hand=100
        )
Beispiel #4
0
    def test_archive(self):
        original_list = Product.by_domain(self.domain.name, wrap=False)

        self.products[0].archive()

        new_list = Product.by_domain(self.domain.name, wrap=False)

        self.assertTrue(
            self.products[0]._id not in [p['_id'] for p in new_list],
            "Archived product still returned by Product.by_domain()"
        )

        self.assertEqual(
            len(new_list),
            len(original_list) - 1
        )

        self.assertEqual(
            len(Product.by_domain(self.domain.name, wrap=False, include_archived=True)),
            len(original_list)
        )

        self.assertEqual(
            SQLProduct.objects.filter(domain=self.domain.name, is_archived=True).count(),
            1
        )

        self.products[0].unarchive()

        self.assertEqual(
            len(original_list),
            len(Product.by_domain(self.domain.name, wrap=False))
        )
Beispiel #5
0
    def product_data(self):
        data = []
        if self.show_inactive:
            products = Product.archived_by_domain(
                domain=self.domain,
                limit=self.limit,
                skip=self.skip(),
            )
        else:
            products = Product.by_domain(
                domain=self.domain,
                limit=self.limit,
                skip=self.skip(),
            )

        for p in products:
            if p.program_id:
                program = Program.get(p.program_id)
            else:
                program = get_or_create_default_program(self.domain)
                p.program_id = program.get_id
                p.save()

            info = p._doc
            info['program'] = program.name
            info['edit_url'] = reverse('commtrack_product_edit', kwargs={'domain': self.domain, 'prod_id': p._id})
            info['archive_action_desc'] = self.get_archive_text(self.show_inactive)
            info['archive_action_text'] = _("Un-Archive") if self.show_inactive else _("Archive")
            info['archive_url'] = reverse(
                'unarchive_product' if self.show_inactive else 'archive_product',
                kwargs={'domain': self.domain, 'prod_id': p._id}
            )
            data.append(info)
        return data
Beispiel #6
0
    def test_archive(self):
        bootstrap_products(self.domain)
        products = sorted(Product.by_domain(self.domain), key=lambda p: p._id)
        original_list = Product.by_domain(self.domain, wrap=False)

        products[0].archive()

        new_list = Product.by_domain(self.domain, wrap=False)

        self.assertTrue(
            products[0]._id not in [p['_id'] for p in new_list],
            "Archived product still returned by Product.by_domain()"
        )

        self.assertEqual(
            len(new_list),
            len(original_list) - 1
        )

        self.assertEqual(
            len(Product.by_domain(self.domain, wrap=False, include_archived=True)),
            len(original_list)
        )

        self.assertEqual(
            SQLProduct.objects.filter(domain=self.domain, is_archived=True).count(),
            1
        )

        products[0].unarchive()

        self.assertEqual(
            len(original_list),
            len(Product.by_domain(self.domain, wrap=False))
        )
Beispiel #7
0
    def delete(self):
        # you cannot delete the default program
        if self.default:
            raise Exception(_('You cannot delete the default program'))

        default = Program.default_for_domain(self.domain)

        sql_products = SQLProduct.objects.filter(domain=self.domain,
                                                 program_id=self.get_id)
        to_save = []
        for product in sql_products.couch_products():
            product['program_id'] = default._id
            to_save.append(product)

            # break up saving in case there are many products
            if len(to_save) > 500:
                Product.bulk_save(to_save)
                to_save = []

        Product.bulk_save(to_save)

        # bulk update sqlproducts
        sql_products.update(program_id=default._id)

        return super(Program, self).delete()
    def handle(self, *args, **options):
        for domain in Domain.get_all():
            if domain['commtrack_enabled']:
                fields_definition = CustomDataFieldsDefinition.get_or_create(
                    domain['name'],
                    'ProductFields'
                )

                product_ids = Product.ids_by_domain(domain['name'])

                existing_field_slugs = set(
                    [field.slug for field in fields_definition.fields]
                )
                for product in iter_docs(Product.get_db(), product_ids):
                    product_data = product.get('product_data', {})
                    for key in product_data.keys():
                        if key and key not in existing_field_slugs:
                            existing_field_slugs.add(key)
                            fields_definition.fields.append(CustomDataField(
                                slug=key,
                                label=key,
                                is_required=False
                            ))

                # Only save a definition for domains which use custom product data
                if fields_definition.fields:
                    fields_definition.save()
 def get_products(self):
     if self.config['program'] and not self.config['product']:
         product_ids = [product.get_id for product in Product.by_program_id(self.config['domain'],
                                                                            self.config['program'])]
     elif self.config['program'] and self.config['product']:
         product_ids = [self.config['product']]
     else:
         product_ids = Product.ids_by_domain(self.config['domain'])
     return product_ids
Beispiel #10
0
def import_products(domain, importer):
    from corehq.apps.products.views import ProductFieldsView
    results = {'errors': [], 'messages': []}
    to_save = []
    product_count = 0
    seen_product_ids = set()

    custom_data_validator = ProductFieldsView.get_validator(domain)

    for row in importer.worksheet:
        try:
            p = Product.from_excel(row, custom_data_validator)
        except Exception, e:
            results['errors'].append(
                _(u'Failed to import product {name}: {ex}'.format(
                    name=row['name'] or '',
                    ex=e,
                ))
            )
            continue

        importer.add_progress()
        if not p:
            # skip if no product is found (or the row is blank)
            continue
        if not p.domain:
            # if product doesn't have domain, use from context
            p.domain = domain
        elif p.domain != domain:
            # don't let user import against another domains products
            results['errors'].append(
                _(u"Product {product_name} belongs to another domain and was not updated").format(
                    product_name=p.name
                )
            )
            continue

        if p.code and p.code in seen_product_ids:
            results['errors'].append(_(
                u"Product {product_name} could not be imported \
                due to duplicated product ids in the excel \
                file"
            ).format(
                product_name=p.name
            ))
            continue
        elif p.code:
            seen_product_ids.add(p.code)

        product_count += 1
        to_save.append(p)

        if len(to_save) > 500:
            Product.get_db().bulk_save(to_save)
            for couch_product in to_save:
                couch_product.sync_to_sql()
            to_save = []
Beispiel #11
0
    def test_programs(self):
        self.domain = bootstrap_domain(TEST_DOMAIN)
        self.addCleanup(self.domain.delete)
        bootstrap_products(self.domain.name)
        self.products = sorted(Product.by_domain(self.domain.name), key=lambda p: p._id)
        self.default_program = Program.by_domain(self.domain.name, wrap=True).one()
        self.new_program = make_program(
            self.domain.name,
            'new program',
            'newprogram'
        )
        self.assertTrue(self.default_program.default)
        self.assertFalse(self.new_program.default)

        with self.assertRaises(Exception) as context:
            self.default_program.delete()

        self.assertEqual(six.text_type(context.exception), 'You cannot delete the default program')

        # assign some product to the new program
        self.products[0].program_id = self.new_program._id
        self.products[0].save()

        # make sure start state is okay
        self.assertEqual(
            2,
            len(Program.by_domain(self.domain.name))
        )
        self.assertEqual(2, self.default_program.get_products_count())
        self.assertEqual(1, self.new_program.get_products_count())
        self.assertEqual(
            self.new_program._id,
            self.products[0].program_id
        )
        self.assertEqual(
            self.new_program._id,
            SQLProduct.objects.get(product_id=self.products[0]._id).program_id
        )

        # stash the id before we delete
        new_program_id = self.new_program._id
        self.new_program.delete()

        with self.assertRaises(ResourceNotFound):
            Program.get(new_program_id)

        self.assertEqual(1, len(Program.by_domain(self.domain.name)))
        self.assertEqual(3, self.default_program.get_products_count())
        self.assertEqual(
            self.default_program._id,
            Product.get(self.products[0]._id).program_id
        )
        self.assertEqual(
            self.default_program._id,
            SQLProduct.objects.get(product_id=self.products[0]._id).program_id
        )
    def setUp(self):
        self.facility = make_loc('test-faciity', 'Test Facility', TEST_DOMAIN, 'Polyclinic')
        self.commodity = Product(domain=TEST_DOMAIN, name='Drug A', code_='ab', unit='cycle')
        self.commodity.save()

        self.commodity2 = Product(domain=TEST_DOMAIN, name='Drug B', code_='cd', unit='cycle')
        self.commodity2.save()

        self.sql_facility = self.facility.sql_location
        self.sql_facility.products = []
        self.sql_facility.save()
    def _create_data(self, domain_name):
        product = Product(domain=domain_name, name="test-product")
        product.save()

        location = Location(domain=domain_name, site_code="testcode", name="test1", location_type="facility")
        location.save()
        self.locations[domain_name] = location.sql_location

        user = CommCareUser.create(domain=domain_name, username="******".format(domain_name), password="******")

        FacilityInCharge.objects.create(user_id=user.get_id, location=location.sql_location)
class EWSTestReminders(TestCase):
    """Moved from EWS"""

    @classmethod
    def setUpClass(cls):
        cls.domain = prepare_domain(TEST_DOMAIN)
        cls.sms_backend_mapping, cls.backend = create_backend()

    def setUp(self):
        self.facility = make_loc('test-faciity', 'Test Facility', TEST_DOMAIN, 'Polyclinic')
        self.commodity = Product(domain=TEST_DOMAIN, name='Drug A', code_='ab', unit='cycle')
        self.commodity.save()

        self.commodity2 = Product(domain=TEST_DOMAIN, name='Drug B', code_='cd', unit='cycle')
        self.commodity2.save()

        self.sql_facility = self.facility.sql_location
        self.sql_facility.products = []
        self.sql_facility.save()

    def test_reminders(self):
        products_reported, products_not_reported = report_status(self.facility.sql_location, days_until_late=1)
        self.assertEqual(len(products_reported), 0)
        self.assertEqual(len(products_not_reported), 0)

        assign_products_to_location(self.facility, [self.commodity])
        products_reported, products_not_reported = report_status(self.facility.sql_location, days_until_late=1)
        self.assertEqual(len(products_reported), 0)

        sql_commodity = SQLProduct.objects.get(product_id=self.commodity.get_id)
        self.assertEqual(products_not_reported[0], sql_commodity)

        sql_commodity2 = SQLProduct.objects.get(product_id=self.commodity2.get_id)

        create_stock_report(self.facility, {'ab': 10})
        products_reported, products_not_reported = report_status(self.facility.sql_location, days_until_late=1)
        self.assertEqual(products_reported[0], sql_commodity)
        self.assertEqual(len(products_not_reported), 0)

        assign_products_to_location(self.facility, [self.commodity, self.commodity2])
        products_reported, products_not_reported = report_status(self.facility.sql_location, days_until_late=1)
        self.assertEqual(products_reported[0], sql_commodity)
        self.assertEqual(products_not_reported[0], sql_commodity2)

        create_stock_report(self.facility, {'cd': 10})
        products_reported, products_not_reported = report_status(self.facility.sql_location, days_until_late=1)
        self.assertTrue(sql_commodity in products_reported)
        self.assertTrue(sql_commodity2 in products_reported)
        self.assertEqual(len(products_not_reported), 0)

    @classmethod
    def tearDownClass(cls):
        cls.backend.delete()
        cls.sms_backend_mapping.delete()
    def test_incomplete_report2(self):
        create_stock_report(self.facility, {'tp': 100}, date=datetime.utcnow())
        self.product.program_id = self.program2.get_id
        self.product.save()
        other_product = Product(
            domain=self.TEST_DOMAIN, name='Test Product2', code_='tp2', unit='each', program_id=self.program.get_id
        )
        other_product.save()
        assign_products_to_location(self.facility, [self.product, other_product])
        generated = list(OnGoingNonReporting(self.TEST_DOMAIN).get_notifications())

        self.assertEqual(len(generated), 0)
    def test_partial_product_stockout(self):
        """Multiple products but only one is stocked out. Should be reported."""
        other_product = Product(domain=self.TEST_DOMAIN, name='Test Product2', code_='tp2', unit='each')
        other_product.save()

        assign_products_to_location(self.facility, [self.product, other_product])

        create_stock_report(self.facility, {'tp': 0})
        create_stock_report(self.facility, {'tp2': 10})

        generated = list(OnGoingStockouts(self.TEST_DOMAIN).get_notifications())
        self.assertEqual(len(generated), 1)
        self.assertEqual(generated[0].user.get_id, self.user.get_id)
    def test_delete(self):
        # assign some product to the new program
        self.products[0].program_id = self.new_program._id
        self.products[0].save()

        # make sure start state is okay
        self.assertEqual(
            2,
            len(Program.by_domain(self.domain.name))
        )
        self.assertEqual(
            2,
            Product.by_program_id(self.domain.name, self.default_program._id).count()
        )
        self.assertEqual(
            1,
            Product.by_program_id(self.domain.name, self.new_program._id).count()
        )
        self.assertEqual(
            self.new_program._id,
            self.products[0].program_id
        )
        self.assertEqual(
            self.new_program._id,
            SQLProduct.objects.get(product_id=self.products[0]._id).program_id
        )

        # stash the id before we delete
        new_program_id = self.new_program._id
        self.new_program.delete()

        with self.assertRaises(ResourceNotFound):
            Program.get(new_program_id)

        self.assertEqual(
            1,
            len(Program.by_domain(self.domain.name))
        )
        self.assertEqual(
            3,
            Product.by_program_id(self.domain.name, self.default_program._id).count()
        )
        self.assertEqual(
            self.default_program._id,
            Product.get(self.products[0]._id).program_id
        )
        self.assertEqual(
            self.default_program._id,
            SQLProduct.objects.get(product_id=self.products[0]._id).program_id
        )
def update_product_availability_facility_data(org_summary):
    # product availability

    facility = Location.get(docid=org_summary.supply_point)
    assert facility.location_type == "FACILITY"
    prods = Product.ids_by_domain(facility.domain)
    for p in prods:
        product_data, created = ProductAvailabilityData.objects.get_or_create(
            product=p,
            supply_point=facility._id,
            date=org_summary.date
        )

        if created:
            # set defaults
            product_data.total = 1
            previous_reports = ProductAvailabilityData.objects.filter(
                product=p,
                supply_point=facility._id,
                date__lt=org_summary.date
            )
            if previous_reports.count():
                prev = previous_reports.order_by("-date")[0]
                product_data.with_stock = prev.with_stock
                product_data.without_stock = prev.without_stock
                product_data.without_data = prev.without_data
            else:
                # otherwise we use the defaults
                product_data.with_stock = 0
                product_data.without_stock = 0
                product_data.without_data = 1
            product_data.save()
        assert (product_data.with_stock + product_data.without_stock + product_data.without_data) == 1, \
            "bad product data config"
    def handle(self, **options):

        self.stdout.write("Processing products...\n")
        products = set()
        total = StockState.objects.count()
        failed = []
        for i, ss in enumerate(StockState.objects.all()):
            if i % 500 == 0:
                self.stdout.write('done {}/{}'.format(i, total))
            if ss.product_id not in products:
                try:
                    product = Product.get(ss.product_id)
                    assert product.doc_type == 'Product'
                    products.add(ss.product_id)
                except (ResourceNotFound, AssertionError):
                    try:
                        case = CommCareCase.get(ss.case_id)
                    except ResourceNotFound:
                        case = CommCareCase()
                    failed.append((ss, case))
        if failed:
            for ss, case in failed:
                self.stdout.write('No product with ID "{}" found! case ID: {}, domain {}'.format(
                    ss.product_id, ss.case_id, case.domain
                ))
            self.stderr.write('{}/{} stock states FAILED check'.format(len(failed), total))
    def chart_data(self):
        def calculate_weeks_remaining(stock_state, date):

            if stock_state.last_modified_date < date:
                if not stock_state.daily_consumption:
                    return 0
                consumption = float(stock_state.daily_consumption) * 7.0
                quantity = float(stock_state.stock_on_hand) - int((date - state.last_modified_date).days / 7.0) \
                    * consumption
                if consumption and consumption > 0 and quantity > 0:
                    return quantity / consumption
            return 0

        stock_states = StockState.include_archived.filter(
            case_id__in=get_relevant_supply_point_ids(self.config['domain'], self.sublocations[0]),
            section_id=STOCK_SECTION_TYPE,
            product_id__in=self.get_products(),
            last_modified_date__lte=self.config['enddate'],
        ).order_by('last_modified_date')

        rows = {}
        for state in stock_states:
            product_name = Product.get(state.product_id).name
            rows[product_name] = []
            weeks = ceil((self.config['enddate'] - self.config['startdate']).days / 7.0)
            for i in range(1, int(weeks + 1)):
                rows[product_name].append({'x': i, 'y': calculate_weeks_remaining(state, self.config['startdate'] +
                                                                                  timedelta(weeks=i))})
        return rows
Beispiel #21
0
 def _column_tuples(self):
     product_ids = [p._id for p in Product.by_domain(self.domain)]
     return sorted(
         list(
             StockState.objects.filter(product_id__in=product_ids).values_list("product_id", "section_id").distinct()
         )
     )
Beispiel #22
0
def sync_requisition_from_openlmis(domain, requisition_id, openlmis_endpoint):
    cases = []
    send_notification = False
    lmis_requisition_details = openlmis_endpoint.get_requisition_details(requisition_id)
    if lmis_requisition_details:
        rec_cases = [c for c in RequisitionCase.get_by_external_id(domain, str(lmis_requisition_details.id)) if c.type == const.REQUISITION_CASE_TYPE]

        if len(rec_cases) == 0:
            products = [product for product in lmis_requisition_details.products if product.skipped == False]
            for product in products:
                pdt = Product.get_by_code(domain, product.code.lower())
                if pdt:
                    case = lmis_requisition_details.to_requisition_case(pdt._id)
                    case.save()
                    if case.requisition_status == 'AUTHORIZED':
                        send_notification = True
                    cases.append(case)
        else:
            for case in rec_cases:
                before_status = case.requisition_status
                if apply_updates(case, lmis_requisition_details.to_dict(case.product_id)):
                    after_status = case.requisition_status
                    case.save()
                    if before_status in ['INITIATED', 'SUBMITTED'] and after_status == 'AUTHORIZED':
                        send_notification = True
                cases.append(case)
        return cases, send_notification
    else:
        return None, False
Beispiel #23
0
    def rows(self):

        def row_in_names(row, names):
            if row in names:
                return True, names.index(row)+1
            else:
                for idx, val in enumerate(names):
                    if unicode(row).lower() in PRODUCT_NAMES.get(val, []):
                        return True, idx+1
            return False, 0

        commandes = ['Comanndes']
        raux = ['Recu']
        taux = ['Taux']
        products = Product.by_domain(self.config['domain'])
        for product in products:
            commandes.append(0)
            raux.append(0)
            taux.append(0)
        names = []

        for product in products:
            names.append(unicode(product.name).lower())
        rows = super(DispDesProducts, self).rows
        for row in rows:
            exits, index = row_in_names(row[0], names)
            if exits:
                commandes[index] = row[1]
                raux[index] = row[2]
                taux[index] = "%d%%" % (100*row[2]['html']/(row[1]['html'] or 1))
        return [commandes, raux, taux]
Beispiel #24
0
    def __init__(self, domain, *args, **kwargs):
        self.domain = domain
        super(ConsumptionForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.label_class = 'col-sm-3 col-md-4 col-lg-2'
        self.helper.field_class = 'col-sm-4 col-md-5 col-lg-3'

        layout = []
        products = Product.by_domain(domain)
        for p in products:
            field_name = 'default_%s' % p._id
            display = _('Default %(product_name)s') % {'product_name': p.name}
            layout.append(field_name)
            self.fields[field_name] = forms.DecimalField(
                label=display,
                required=False,
                initial=get_default_monthly_consumption(
                    self.domain,
                    p._id,
                    None,
                    None
                )
            )

        layout.append(hqcrispy.FormActions(
            ButtonHolder(
                Submit('submit', ugettext_lazy('Update Default Consumption Info'))
            )
        ))
        self.helper.layout = Layout(*layout)
Beispiel #25
0
 def product_from_code(self, prod_code):
     """return the product doc referenced by prod_code"""
     prod_code = prod_code.lower()
     p = Product.get_by_code(self.domain.name, prod_code)
     if p is None:
         raise SMSError('invalid product code "%s"' % prod_code)
     return p
Beispiel #26
0
 def wrap_from_json(cls, obj, domain, location_id):
     product = Product.get_by_code(domain, obj['product'])
     obj['product'] = product._id
     obj['location_id'] = location_id
     obj['external_id'] = obj['id']
     del obj['id']
     return cls(**obj)
Beispiel #27
0
    def post(self, request, *args, **kwargs):
        InputStockFormSet = formset_factory(InputStockForm)
        formset = InputStockFormSet(request.POST)
        if formset.is_valid():
            try:
                sql_location = SQLLocation.objects.get(site_code=kwargs['site_code'], domain=self.domain)
            except SQLLocation.DoesNotExist:
                raise Http404()
            text = ''
            for form in formset:
                product = Product.get(docid=form.cleaned_data['product_id'])
                if form.cleaned_data['stock_on_hand'] is not None:
                    text += '{} {}.{} '.format(
                        product.code, form.cleaned_data['stock_on_hand'], form.cleaned_data['receipts'] or 0
                    )

                amount = form.cleaned_data['default_consumption']
                if amount is not None:
                    set_default_consumption_for_supply_point(
                        self.domain, product.get_id, sql_location.supply_point_id, amount
                    )
            if text:
                WebSubmissionHandler(self.request.couch_user, self.domain, Msg(text), sql_location).handle()
            url = make_url(
                StockStatus,
                self.domain,
                '?location_id=%s&filter_by_program=%s&startdate='
                '&enddate=&report_type=&filter_by_product=%s',
                (sql_location.location_id, ALL_OPTION, ALL_OPTION)
            )
            return HttpResponseRedirect(url)
        context = self.get_context_data(**kwargs)
        context['formset'] = formset
        return self.render_to_response(context)
Beispiel #28
0
 def drilldown_map(self):
     options = [{"val": ALL_OPTION, "text": "All", "next": []}]
     for program in Program.by_domain(self.domain):
         products = [{"val": ALL_OPTION, "text": "All", "next": []}]
         for product in Product.by_program_id(self.domain, program._id):
             products.append({"val": product.get_id, "text": product.name + ' (%s)' % product.code})
         options.append({"val": program.get_id, "text": program.name, "next": products})
     return options
 def setUp(self):
     self.datapath = os.path.join(os.path.dirname(__file__), 'data')
     self.api = MockOpenLMISEndpoint("uri://mock/lmis/endpoint", username='******', password='******')
     initial_bootstrap(TEST_DOMAIN)
     bootstrap_domain(TEST_DOMAIN)
     delete_all_cases()
     for product in Product.by_domain(TEST_DOMAIN):
         product.delete()
Beispiel #30
0
def all_sms_codes(domain):
    config = CommtrackConfig.for_domain(domain)

    actions = dict((action.keyword, action) for action in config.actions)
    products = dict((p.code, p) for p in Product.by_domain(domain))

    sms_codes = zip(('action', 'product'), (actions, products))
    return dict(itertools.chain(*([(k.lower(), (type, v)) for k, v in six.iteritems(codes)] for type, codes in sms_codes)))
    def setUp(self):
        super(UrgentStockoutNotificationTestCase, self).setUp()
        self.product = Product(domain=self.TEST_DOMAIN,
                               name='Test Product',
                               code_='tp',
                               unit='each',
                               program_id=self.program.get_id)
        self.product.save()

        self.country = make_loc('test-country', 'Test country',
                                self.TEST_DOMAIN, 'country')
        self.region = make_loc('test-region',
                               'Test Region',
                               self.TEST_DOMAIN,
                               'region',
                               parent=self.country)
        self.district = make_loc('test-district',
                                 'Test District',
                                 self.TEST_DOMAIN,
                                 'district',
                                 parent=self.region)

        self.facility = make_loc('test-facility', 'Test Facility',
                                 self.TEST_DOMAIN, 'Polyclinic', self.district)
        self.other_facility = make_loc('test-facility2', 'Test Facility 2',
                                       self.TEST_DOMAIN, 'Polyclinic',
                                       self.district)
        self.last_facility = make_loc('test-facility3', 'Test Facility 3',
                                      self.TEST_DOMAIN, 'Polyclinic',
                                      self.district)
        self.user = bootstrap_web_user(username='******',
                                       domain=self.TEST_DOMAIN,
                                       phone_number='+4444',
                                       location=self.region,
                                       email='*****@*****.**',
                                       password='******',
                                       user_data={})
Beispiel #32
0
    def test_delete(self):
        # assign some product to the new program
        self.products[0].program_id = self.new_program._id
        self.products[0].save()

        # make sure start state is okay
        self.assertEqual(2, len(Program.by_domain(self.domain.name)))
        self.assertEqual(
            2,
            Product.by_program_id(self.domain.name,
                                  self.default_program._id).count())
        self.assertEqual(
            1,
            Product.by_program_id(self.domain.name,
                                  self.new_program._id).count())
        self.assertEqual(self.new_program._id, self.products[0].program_id)
        self.assertEqual(
            self.new_program._id,
            SQLProduct.objects.get(product_id=self.products[0]._id).program_id)

        # stash the id before we delete
        new_program_id = self.new_program._id
        self.new_program.delete()

        with self.assertRaises(ResourceNotFound):
            Program.get(new_program_id)

        self.assertEqual(1, len(Program.by_domain(self.domain.name)))
        self.assertEqual(
            3,
            Product.by_program_id(self.domain.name,
                                  self.default_program._id).count())
        self.assertEqual(self.default_program._id,
                         Product.get(self.products[0]._id).program_id)
        self.assertEqual(
            self.default_program._id,
            SQLProduct.objects.get(product_id=self.products[0]._id).program_id)
Beispiel #33
0
    def test_selective_product_sync(self):
        user = self.user

        expected_xml = self.generate_product_fixture_xml(user)

        product_list = Product.by_domain(user.domain)
        self._initialize_product_names(len(product_list))

        fixture_original = call_fixture_generator(product_fixture_generator,
                                                  user)[1]
        deprecated_generate_restore_payload(self.domain_obj, user)
        self.assertXmlEqual(
            expected_xml,
            ElementTree.tostring(fixture_original, encoding='utf-8'))

        first_sync = self._get_latest_synclog()

        # make sure the time stamp on this first sync is
        # not on the same second that the products were created
        first_sync.date += datetime.timedelta(seconds=1)

        # second sync is before any changes are made, so there should
        # be no products synced
        fixture_pre_change = call_fixture_generator(product_fixture_generator,
                                                    user,
                                                    last_sync=first_sync)
        deprecated_generate_restore_payload(self.domain_obj, user)
        self.assertEqual([], fixture_pre_change,
                         "Fixture was not empty on second sync")

        second_sync = self._get_latest_synclog()

        self.assertTrue(first_sync._id != second_sync._id)

        # save should make the product more recently updated than the
        # last sync
        for product in product_list:
            product.save()

        # now that we've updated a product, we should get
        # product data in sync again
        fixture_post_change = call_fixture_generator(product_fixture_generator,
                                                     user,
                                                     last_sync=second_sync)[1]

        # regenerate the fixture xml to make sure it is still legit
        self.assertXmlEqual(
            expected_xml,
            ElementTree.tostring(fixture_post_change, encoding='utf-8'))
Beispiel #34
0
def archive_product(request, domain, prod_id, archive=True):
    """
    Archive product
    """
    product = Product.get(prod_id)
    product.archive()
    return json_response({
        'success':
        True,
        'message':
        _("Product '{product_name}' has successfully been {action}.").format(
            product_name=product.name,
            action="archived",
        )
    })
    def test_product_type_filter(self):
        """User can recieve missing notifications for only certain product type."""
        bootstrap_web_user(
            username='******', domain=self.TEST_DOMAIN, phone_number='+44445', location=self.district,
            password='******', email='*****@*****.**', user_data={}, program_id=self.program.get_id
        )

        other_product = Product(domain=self.TEST_DOMAIN, name='Test Product2', code_='tp2', unit='each')
        other_product2 = Product(domain=self.TEST_DOMAIN, name='Test Product3', code_='tp3', unit='each')
        other_product.save()
        other_product2.save()
        assign_products_to_location(self.facility, [self.product, other_product, other_product2])

        generated = list(OnGoingNonReporting(self.TEST_DOMAIN).get_notifications())

        self.assertEqual(len(generated), 1)
        self.assertEqual(generated[0].user.get_id, self.user.get_id)
Beispiel #36
0
    def setUp(self):
        super(CommTrackTest, self).setUp()
        # might as well clean house before doing anything
        delete_all_xforms()
        delete_all_cases()
        delete_all_sync_logs()

        StockReport.objects.all().delete()
        StockTransaction.objects.all().delete()

        self.backend, self.backend_mapping = setup_default_sms_test_backend()

        self.domain = bootstrap_domain(TEST_DOMAIN)
        bootstrap_location_types(self.domain.name)
        bootstrap_products(self.domain.name)
        self.ct_settings = CommtrackConfig.for_domain(self.domain.name)
        self.ct_settings.consumption_config = ConsumptionConfig(
            min_transactions=0,
            min_window=0,
            optimal_window=60,
            min_periods=0,
        )
        # todo: remove?
        if self.requisitions_enabled:
            self.ct_settings.requisition_config = get_default_requisition_config(
            )

        self.ct_settings.save()

        self.domain = Domain.get(self.domain._id)

        self.loc = make_loc('loc1')
        self.sp = self.loc.linked_supply_point()
        self.users = [
            bootstrap_user(self, **user_def)
            for user_def in self.user_definitions
        ]

        # everyone should be in a group.
        self.group = Group(domain=TEST_DOMAIN,
                           name='commtrack-folks',
                           users=[u._id for u in self.users],
                           case_sharing=True)
        self.group._id = self.sp.owner_id
        self.group.save()
        self.products = sorted(Product.by_domain(self.domain.name),
                               key=lambda p: p._id)
        self.assertEqual(3, len(self.products))
Beispiel #37
0
 def post(self, request, *args, **kwargs):
     InputStockFormSet = formset_factory(InputStockForm)
     formset = InputStockFormSet(request.POST)
     if formset.is_valid():
         try:
             location = SQLLocation.objects.get(
                 site_code=kwargs['site_code'], domain=self.domain)
         except SQLLocation.DoesNotExist:
             raise Http404()
         data = []
         for form in formset:
             product = Product.get(docid=form.cleaned_data['product_id'])
             if form.cleaned_data['receipts']:
                 data.append(
                     StockTransactionHelper(
                         domain=self.domain,
                         location_id=location.location_id,
                         case_id=location.supply_point_id,
                         product_id=product.get_id,
                         action=const.StockActions.RECEIPTS,
                         quantity=form.cleaned_data['receipts']), )
             if form.cleaned_data['stock_on_hand'] is not None:
                 data.append(
                     StockTransactionHelper(
                         domain=self.domain,
                         location_id=location.location_id,
                         case_id=location.supply_point_id,
                         product_id=product.get_id,
                         action=const.StockActions.STOCKONHAND,
                         quantity=form.cleaned_data['stock_on_hand']), )
         if data:
             unpacked_data = {
                 'timestamp': datetime.utcnow(),
                 'user': self.request.couch_user,
                 'phone': 'ewsghana-input-stock',
                 'location': location.couch_location,
                 'transactions': data,
             }
             process(self.domain, unpacked_data)
         url = make_url(
             StockLevelsReport, self.domain,
             '?location_id=%s&filter_by_program=%s&startdate='
             '&enddate=&report_type=&filter_by_product=%s',
             (location.location_id, ALL_OPTION, ALL_OPTION))
         return HttpResponseRedirect(url)
     context = self.get_context_data(**kwargs)
     context['formset'] = formset
     return self.render_to_response(context)
Beispiel #38
0
    def sms_format(self):
        if self.requisition_status == RequisitionStatus.REQUESTED:
            section = 'ct-requested'
        elif self.requisition_status == RequisitionStatus.APPROVED:
            section = 'ct-approved'
        else:
            section = 'stock'

        formatted_strings = []
        states = StockState.objects.filter(case_id=self._id,
                                           section_id=section)
        for state in states:
            product = Product.get(state.product_id)
            formatted_strings.append('%s:%d' %
                                     (product.code, state.stock_on_hand))
        return ' '.join(sorted(formatted_strings))
Beispiel #39
0
 def __init__(self, domain, *args, **kwargs):
     self.domain = domain
     super(ConsumptionForm, self).__init__(*args, **kwargs)
     products = Product.by_domain(domain)
     for p in products:
         field_name = 'default_%s' % p._id
         display = _('Default %(product_name)s') % {'product_name': p.name}
         self.fields[field_name] = forms.DecimalField(
             label=display,
             required=False,
             initial=get_default_monthly_consumption(
                 self.domain,
                 p._id,
                 None,
                 None
             )
         )
Beispiel #40
0
    def include_consumption(self):
        if bool(
            self.include_consumption_flag and
            self.domain_obj.commtrack_settings.individual_consumption_defaults
        ):
            # we'll be needing these, so init 'em:
            self.products = Product.by_domain(self.domain)
            self.product_codes = [p.code for p in self.products]
            self.supply_point_map = get_supply_point_ids_in_domain_by_location(
                self.domain)
            self.administrative_types = {
                lt.name for lt in self.location_types
                if lt.administrative

            }
            return True
        return False
Beispiel #41
0
    def get_prod_data(self):
        sp_ids = get_relevant_supply_point_ids(self.domain,
                                               self.active_location)

        stock_states = StockState.objects.filter(
            case_id__in=sp_ids,
            last_modified_date__lte=self.datespan.enddate_utc,
            last_modified_date__gte=self.datespan.startdate_utc,
            section_id=STOCK_SECTION_TYPE)

        stock_states = stock_states.order_by('product_id')

        if self.program_id:
            stock_states = stock_states.filter(
                product_id__in=product_ids_filtered_by_program(
                    self.domain, self.program_id))

        product_grouping = {}
        for state in stock_states:
            status = state.stock_category
            if state.product_id in product_grouping:
                product_grouping[state.product_id][status] += 1
                product_grouping[state.product_id]['facility_count'] += 1

            else:
                product_grouping[state.product_id] = {
                    'obj': Product.get(state.product_id),
                    'stockout': 0,
                    'understock': 0,
                    'overstock': 0,
                    'adequate': 0,
                    'nodata': 0,
                    'facility_count': 1
                }
                product_grouping[state.product_id][status] = 1

        for product in product_grouping.values():
            yield [
                product['obj'].name,
                product['facility_count'],
                100.0 * product['stockout'] / product['facility_count'],
                100.0 * product['understock'] / product['facility_count'],
                100.0 * product['adequate'] / product['facility_count'],
                100.0 * product['overstock'] / product['facility_count'],
                100.0 * product['nodata'] / product['facility_count'],
            ]
Beispiel #42
0
 def product_sync(self, ilsgateway_product):
     product = Product.get_by_code(self.domain, ilsgateway_product.sms_code)
     product_dict = {
         'domain': self.domain,
         'name': ilsgateway_product.name,
         'code': ilsgateway_product.sms_code,
         'unit': str(ilsgateway_product.units),
         'description': ilsgateway_product.description,
     }
     if product is None:
         product = Product(**product_dict)
         product.save()
     else:
         if apply_updates(product, product_dict):
             product.save()
     return product
Beispiel #43
0
def all_sms_codes(domain):
    config = CommtrackConfig.for_domain(domain)

    actions = dict((action.keyword, action) for action in config.actions)
    products = dict((p.code, p) for p in Product.by_domain(domain))
    commands = {
        config.multiaction_keyword: {
            'type': 'stock_report_generic',
            'caption': 'Stock Report'
        },
    }

    sms_codes = zip(('action', 'product', 'command'),
                    (actions, products, commands))
    return dict(
        itertools.chain(*([(k.lower(), (type, v))
                           for k, v in codes.iteritems()]
                          for type, codes in sms_codes)))
Beispiel #44
0
    def setUpClass(cls):
        super(StockStateTest, cls).setUpClass()
        cls.domain_obj = util.bootstrap_domain(cls.domain)
        util.bootstrap_location_types(cls.domain)
        util.bootstrap_products(cls.domain)
        cls.ct_settings = CommtrackConfig.for_domain(cls.domain)
        cls.ct_settings.use_auto_consumption = True
        cls.ct_settings.consumption_config = ConsumptionConfig(
            min_transactions=0,
            min_window=0,
            optimal_window=60,
            min_periods=0,
        )
        cls.ct_settings.save()

        cls.loc = util.make_loc('loc1', domain=cls.domain)
        cls.sp = cls.loc.linked_supply_point()
        cls.products = sorted(Product.by_domain(cls.domain), key=lambda p: p._id)
Beispiel #45
0
def recalculate_domain_consumption(domain):
    """
    Given a domain, recalculate all saved consumption settings in that domain.
    """
    # note: might get slow as this gets huge
    found_doc_ids = DocDomainMapping.objects.filter(
        domain_name=domain,
        doc_type='CommCareCase',
    ).values_list('doc_id', flat=True)
    products = Product.by_domain(domain)
    for supply_point_id in found_doc_ids:
        for product in products:
            filtered_transactions = StockTransaction.objects.filter(
                case_id=supply_point_id,
                product_id=product._id,
                section_id=const.SECTION_TYPE_STOCK,
            ).order_by('-report__date', '-pk')
            if filtered_transactions:
                update_stock_state_for_transaction(filtered_transactions[0])
Beispiel #46
0
 def tearDownClass(cls):
     MobileBackend.load_by_name(TEST_DOMAIN, TEST_BACKEND).delete()
     CommCareUser.get_by_username('stella').delete()
     CommCareUser.get_by_username('bella').delete()
     CommCareUser.get_by_username('trella').delete()
     CommCareUser.get_by_username('msd_person').delete()
     for product in Product.by_domain(TEST_DOMAIN):
         product.delete()
     SQLProduct.objects.all().delete()
     ILSGatewayConfig.for_domain(TEST_DOMAIN).delete()
     DocDomainMapping.objects.all().delete()
     Location.by_site_code(TEST_DOMAIN, 'loc1').delete()
     Location.by_site_code(TEST_DOMAIN, 'loc2').delete()
     Location.by_site_code(TEST_DOMAIN, 'dis1').delete()
     Location.by_site_code(TEST_DOMAIN, 'reg1').delete()
     Location.by_site_code(TEST_DOMAIN, 'moh1').delete()
     SQLLocation.objects.all().delete()
     generator.delete_all_subscriptions()
     Domain.get_by_name(TEST_DOMAIN).delete()
Beispiel #47
0
    def handle(self, **options):

        self.stdout.write("Processing products...\n")
        products = set()
        total = StockState.objects.count()
        failed = []
        for i, ss in enumerate(StockState.objects.all()):
            if i % 500 == 0:
                self.stdout.write('done {}/{}'.format(i, total))
            if ss.product_id not in products:
                try:
                    product = Product.get(ss.product_id)
                    assert product.doc_type == 'Product'
                    products.add(ss.product_id)
                except (ResourceNotFound, AssertionError):
                    try:
                        case = CommCareCase.get(ss.case_id)
                    except ResourceNotFound:
                        case = CommCareCase()
                    failed.append((ss, case))
Beispiel #48
0
    def setUp(self):
        super(XMLTest, self).setUp()
        self.domain = util.bootstrap_domain(util.TEST_DOMAIN)
        util.bootstrap_location_types(self.domain.name)
        util.bootstrap_products(self.domain.name)
        self.products = sorted(Product.by_domain(self.domain.name), key=lambda p: p._id)
        self.ct_settings = CommtrackConfig.for_domain(self.domain.name)
        self.ct_settings.consumption_config = ConsumptionConfig(
            min_transactions=0,
            min_window=0,
            optimal_window=60,
            min_periods=0,
        )
        self.ct_settings.save()
        self.domain = Domain.get(self.domain._id)

        self.loc = make_loc('loc1')
        self.sp = self.loc.linked_supply_point()
        self.users = [util.bootstrap_user(self, **user_def) for user_def in self.user_definitions]
        self.user = self.users[0]
Beispiel #49
0
    def copy_products(self):
        from corehq.apps.products.models import Product
        from corehq.apps.programs.models import Program
        from corehq.apps.products.views import ProductFieldsView

        self._copy_custom_data(ProductFieldsView.field_type)

        program_map = {}
        programs = Program.by_domain(self.existing_domain)
        for program in programs:
            old_id, new_id = self.save_couch_copy(program, self.new_domain)
            program_map[old_id] = new_id

        products = Product.by_domain(self.existing_domain)
        for product in products:
            if product.program_id:
                try:
                    product.program_id = program_map[product.program_id]
                except:
                    self.stderr('Missing program {} for product {}'.format(product.program_id, product._id))
            self.save_couch_copy(product, self.new_domain)
Beispiel #50
0
    def tearDownClass(cls):
        delete_domain_phone_numbers(TEST_DOMAIN)
        if cls.sms_backend_mapping.id is not None:
            cls.sms_backend_mapping.delete()
        if cls.sms_backend.id is not None:
            cls.sms_backend.delete()
        users = get_user_docs_by_username([
            'stella',
            'bella',
            'trella',
            'msd_person',
        ])
        if users:
            CommCareUser.bulk_delete([
                CommCareUser.wrap_correctly(user)
                for user in users
            ])

        for product in Product.by_domain(TEST_DOMAIN):
            product.delete()
        SQLProduct.objects.all().delete()
        ils_gateway_config = ILSGatewayConfig.for_domain(TEST_DOMAIN)
        if ils_gateway_config:
            ils_gateway_config.delete()
        DocDomainMapping.objects.all().delete()
        for site_code in [
            'loc1',
            'loc2',
            'dis1',
            'reg1',
            'moh1',
        ]:
            location = cls.get_location_by_site_code(site_code)
            if location:
                location.delete()
        SQLLocation.objects.all().delete()
        test_domain = Domain.get_by_name(TEST_DOMAIN, strict=True)
        if test_domain:
            test_domain.delete()
        super(ILSTestScript, cls).tearDownClass()
Beispiel #51
0
def approve_requisition(requisition_cases, openlmis_endpoint):
    groups = defaultdict(list)
    for case in requisition_cases:
        groups[case.external_id].append(case)

    for group in groups.keys():
        if (group):
            cases = groups.get(group)
            products = []
            approver = CommCareUser.get(cases[0].user_id)
            for rec in cases:
                product = Product.get(rec.product_id)
                products.append({
                    "productCode": product.code,
                    "quantityApproved": rec.amount_approved
                })

            approve_data = {
                "approverName": approver.human_friendly_name,
                "products": products
            }
            openlmis_endpoint.approve_requisition(approve_data, group)
    def test_should_import_consumption(self):
        existing = make_loc('existingloc', type='state')
        sp = make_supply_point(self.loc.domain, existing)

        data = {
            'site_code': existing.site_code,
            'name': 'existingloc',
            'consumption': {
                'pp': 77
            },
        }

        import_location(self.domain.name, 'state', data)

        self.assertEqual(
            float(
                get_default_consumption(
                    self.domain.name,
                    Product.get_by_code(self.domain.name, 'pp')._id,
                    'state',
                    sp._id,
                )), 77 / DAYS_IN_MONTH)
Beispiel #53
0
    def handle(self, *args, **options):
        self.stdout.write("Processing products...\n")

        relevant_ids = set([
            r['id'] for r in Product.get_db().view(
                'commtrack/products',
                reduce=False,
            ).all()
        ])

        to_save = []

        for product in iter_docs(Product.get_db(), relevant_ids):
            if 'last_modified' not in product or not product['last_modified']:
                product['last_modified'] = datetime.utcnow().isoformat()
                to_save.append(product)

                if len(to_save) > 500:
                    Product.bulk_save(to_save)
                    to_save = []

        if to_save:
            Product.bulk_save(to_save)

        self.stdout.write("Processing programs...\n")

        relevant_ids = set([
            r['id'] for r in Program.get_db().view(
                'commtrack/programs',
                reduce=False,
            ).all()
        ])

        to_save = []

        for program in iter_docs(Program.get_db(), relevant_ids):
            if 'last_modified' not in program or not program['last_modified']:
                program['last_modified'] = datetime.utcnow().isoformat()
                to_save.append(program)

                if len(to_save) > 500:
                    Program.get_db().bulk_save(to_save)
                    to_save = []

        if to_save:
            Program.get_db().bulk_save(to_save)
Beispiel #54
0
 def tearDownClass(cls):
     delete_domain_phone_numbers(TEST_DOMAIN)
     if cls.sms_backend_mapping.id is not None:
         cls.sms_backend_mapping.delete()
     if cls.sms_backend.id is not None:
         cls.sms_backend.delete()
     for username in [
         'stella',
         'bella',
         'trella',
         'msd_person',
     ]:
         user = CommCareUser.get_by_username(username)
         if user:
             user.delete()
     for product in Product.by_domain(TEST_DOMAIN):
         product.delete()
     SQLProduct.objects.all().delete()
     ils_gateway_config = ILSGatewayConfig.for_domain(TEST_DOMAIN)
     if ils_gateway_config:
         ils_gateway_config.delete()
     DocDomainMapping.objects.all().delete()
     for site_code in [
         'loc1',
         'loc2',
         'dis1',
         'reg1',
         'moh1',
     ]:
         location = Location.by_site_code(TEST_DOMAIN, site_code)
         if location:
             location.delete()
     SQLLocation.objects.all().delete()
     generator.delete_all_subscriptions()
     test_domain = Domain.get_by_name(TEST_DOMAIN)
     if test_domain:
         test_domain.delete()
     super(ILSTestScript, cls).tearDownClass()
Beispiel #55
0
def unarchive_product(request, domain, prod_id, archive=True):
    """
    Unarchive product
    """
    product = Product.get(prod_id)
    try:
        product.unarchive()
    except DuplicateProductCodeException:
        success = False
        message = _("Another product is already using the Product ID '{product_id}'").format(
            product_id=product.code
        )
    else:
        success = True
        message = _("Product '{product_name}' has successfully been {action}.").format(
            product_name=product.name,
            action="unarchived",
        )
    return json_response({
        'success': success,
        'message': message,
        'product_id': prod_id
    })
Beispiel #56
0
    def setUpClass(cls):
        super(StockStateTest, cls).setUpClass()
        cls.domain_obj = util.bootstrap_domain(cls.domain)
        util.bootstrap_location_types(cls.domain)
        util.bootstrap_products(cls.domain)
        cls.ct_settings = SQLCommtrackConfig.for_domain(cls.domain)
        cls.ct_settings.use_auto_consumption = True
        cls.ct_settings.sqlconsumptionconfig = SQLConsumptionConfig(
            min_transactions=0,
            min_window=0,
            optimal_window=60,
        )
        cls.ct_settings.save()
        cls.ct_settings.sqlconsumptionconfig.commtrack_settings = cls.ct_settings
        cls.ct_settings.sqlconsumptionconfig.save()

        cls.loc = util.make_loc('loc1', domain=cls.domain)
        cls.sp = cls.loc.linked_supply_point()
        cls.products = sorted(Product.by_domain(cls.domain),
                              key=lambda p: p._id)

        cls.process_ledger_changes = process_pillow_changes(
            'LedgerToElasticsearchPillow')
Beispiel #57
0
def recalculate_domain_consumption(domain):
    """
    Given a domain, recalculate all saved consumption settings in that domain.
    """
    # note: might get slow as this gets huge
    found_doc_ids = DocDomainMapping.objects.filter(
        domain_name=domain,
        doc_type='CommCareCase',
    ).values_list('doc_id', flat=True)
    products = Product.by_domain(domain)
    for supply_point_id in found_doc_ids:
        for product in products:
            try:
                latest_transaction = StockTransaction.get_ordered_transactions_for_stock(
                    supply_point_id, const.SECTION_TYPE_STOCK, product._id)[0]
            except IndexError:
                pass
            else:
                state = get_stock_state_for_transaction(latest_transaction)
                daily_consumption = get_consumption_for_ledger(state)
                state.daily_consumption = daily_consumption
                with drop_connected_signals(post_save):
                    state.save()
Beispiel #58
0
def sync_openlmis_product(domain, program, lmis_product):
    product = get_product(domain, lmis_product)
    product_dict = {
        'domain': domain,
        'name': lmis_product.name,
        'code': lmis_product.code,
        'unit': str(lmis_product.unit),
        'description': lmis_product.description,
        'category': lmis_product.category,
        'program_id': program._id,
    }
    if product is None:
        product = Product(**product_dict)
        product.save()
    else:
        if apply_updates(product, product_dict):
            product.save()
    return product
Beispiel #59
0
    def test_product_fixture_cache(self):
        user = self.user

        expected_xml = self.generate_product_fixture_xml(user)

        fixture_original = call_fixture_generator(product_fixture_generator,
                                                  user)[1]
        self.assertXmlEqual(expected_xml, fixture_original)

        product = Product.by_domain(user.domain)[0]
        product.name = 'new_name'
        super(Product, product).save()  # save but skip clearing the cache

        fixture_cached = call_fixture_generator(product_fixture_generator,
                                                user)[1]
        self.assertXmlEqual(expected_xml, fixture_cached)

        # This will update all the products and re-save them.
        expected_xml_new = self.generate_product_fixture_xml(user)

        fixture_cached = call_fixture_generator(product_fixture_generator,
                                                user)[1]
        self.assertXmlEqual(expected_xml_new, fixture_cached)
        self.assertXMLNotEqual(expected_xml_new, expected_xml)
    def test_should_import_consumption(self):
        parent = make_loc('originalparent', type='village')
        existing = make_loc('existingloc', type='outlet', parent=parent)
        sp = existing.linked_supply_point()

        data = {
            'site_code': existing.site_code,
            'name': 'existingloc',
            'parent_site_code': parent.site_code,
            'consumption': {
                'pp': 77
            },
        }

        import_location(self.domain.name, 'outlet', data)

        self.assertEqual(
            float(
                get_default_consumption(
                    self.domain.name,
                    Product.get_by_code(self.domain.name, 'pp')._id,
                    'state',
                    sp.case_id,
                )), 77 / DAYS_IN_MONTH)